Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Thursday, September 6, 2012

AMQP, RabbitMQ and round robin

I'm working on a set of examples of how to use RabbitMQ from different languages. Among other things I've worked on reviewing the ruby AMQP gem examples. Unfortunately when it came to demonstrating multiple consumers (a sort of scalability example) I hit a snag: even though I have had 4 consumers only the first one was used.

After setting the number of test messages to a really high number things were finally looking up - the second and third and forth consumers were involved. But that sucked big time and to prove it I started digging further to find out what actually makes it do the things it does.

:prefetch => 1 was the setting (as stated on some stackoverflow.com page) but setting it alone didn't do the trick because that made the channel get only one message and that was it. To continue receiving messages they have had to be ack'ed.

Talking is cheap - here's the example code



Have fun!

Wednesday, July 11, 2012

Ruby and Memcached tricks

I love Ruby. It's a great language. I love almost everything about it (maybe besides the symbol syntax... but that's just me I guess).

Today I fell in love with the alias method :)
require 'memcached'
cache = Memcached.new "localhost:11211"
cache.set "message", "Hello, world!"
puts cache.get "message"
All is nice up to the get and set methods. Wouldn't it be nice to use the cache["message"] syntax?
class Memcached
  alias :"[]" :get
  alias :"[]=" :set
end
And then:
cache["message"] = "Hello"
puts cache["message"]

And live is good again :)

Error installing memcached gem

I've been struggling to install memcached gem on my Ubuntu 12.04 box. Some error came out when installing native extensions:
rlibmemcached_wrap.c: In function ‘Init_rlibmemcached’:
rlibmemcached_wrap.c:13736:3: error: implicit declaration of function ‘sasl_client_init’ [-Werror=implicit-function-declaration]
rlibmemcached_wrap.c:13736:33: error: ‘SASL_OK’ undeclared (first use in this function)
cc1: some warnings being treated as errors
make: *** [rlibmemcached_wrap.o] Error 1

A quick look at what uncle Google has to say about it didn't reveal anything at first glance. A deeper search gave me the following address:

https://github.com/evan/memcached/issues/17

Basically the problem is that one needs to install libsasl2-dev package for this to work.

And live is good again :)

Saturday, May 28, 2011

Warbler 1.3.1 is here!

Finally the fix that I mentioned here has found its way to the next release! What this means is that when you install Warbler now and you get the version 1.3.1 then you're again capable of using the config.gems option to bundle gems with your web application using Warbler configuration file alone.

Here's an ultra simplistic example to show how it works:
config.ru (the Rack application):

run lambda { |env| [ 200, [ "Content-Type" => "text/plain" ], "Hello, world!" }

Warbler::Config.new do |config|
config.gems = ["sinatra"] # this is just an example here...
end
With that in place you can now run
jruby -S warble
and have the .war file created for you in a matter of seconds.

And live is good again :)

Sunday, May 15, 2011

The easy but you have to know it...

Yeah, this is the one that is probably make me look like a complete newbie. I've been developing apps in Ruby mostly on Ubuntu but lately I've turned back to Windows and found out that on this platform not everything is taken for granted like it was on Ubuntu. So for that reason I'm making this note so that I don't forget.

If you're installing Ruby gems on Windows and they require compilation of some native extensions (like the JSON thing or Thin) then you need a C compiler to do that. In fact you can do that in multiple ways but there's one easy one that'll take the pain out of your neck in seconds.

What you do is you download the DevKit package, un-7zip it (it's actually a self-extracting archive so that's easy), cd to the directory where you unzipped it and execute the following 3 commands:
ruby dk.rb init
ruby dk.rb review (and make sure your Ruby installation is at correct place)
ruby dk.rb install
With that in place test it by issuing for example:
gem install json
and you should see the following
Fetching: json-1.5.1.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
Successfully installed json-1.5.1
1 gem installed
Have fun!

Wednesday, May 11, 2011

Cross-origin resource sharing

Today I've stumbled upon quite an interesting topic while watching this video from MIX11. Around 40th minute Giorgio Sardo brought up the topic of cross-site Ajax calls. At first I thought "OK, yet another proprietary extension in IE9" but then I started googling and what I found (and subsequently here) has exceeded my wildest expectations. As it turns out it is implemented in all modern browsers. There's a catch to it: the server needs to be aware that such a request will come and attach a specific HTTP header in response.

Since I don't do well with plain text explanations I've put together a Sinatra client and a Rack server to demonstrate this feature.

Client


This is the client code using jQuery's load method to do the Ajax heavy lifting:
$("body").load("http://localhost:9292/"); 

No surprise there, right? It looks like a regular Ajax request. The difference here is that it queries localhost on a different port (9292 - default Rack port) than the one that the request originated from (4567 - default Sinatra port).

Server


Let's see how we can respond to such a request using a pure Rack application.
run lambda { |env| [ 
200, 
{ 
  'Content-Type'=>'text/html', 
  'Access-Control-Allow-Origin' => env['HTTP_ORIGIN'] || '*',
  'Access-Control-Allow-Headers' => 'X-Requested-With'
}, 
env.inspect 
] }

The key here is the line that defines the Access-Control-Allow-Origin response header. When it's set to * it means that everyone can access this resource from everywhere. It's a sort of catch-all if you will. The value of env['HTTP_ORIGIN'] is the value sent by the browser to the server saying "Hey, I'm calling from here. Can I access your resource please?" And if the server agrees (which it does from everywhere at this point) the browser will honor the response and return the data back to the script. The Access-Control-Allow-Headers header is sometimes required for example by ExtJS' Ajax calls.

Here's the example for your convenience. You can start it by issuing the following commands:
cd server
start ruby -S rackup
cd ..\client
start ruby client.rb

After that open your favorite browser (I sure hope it's not IE < 8), navigate to http://localhost:4567 and observe the environment string from the server dumped onto your screen.
The client is obviously written in Sinatra, the best micro web framework ever and the server is a pure Rack application.

Sunday, May 8, 2011

Going ultra simple with JRuby, Tomcat and Rack

This one is for those that don't believe that web applications can be written in a single line :D With Rack and Warbler it is actually possible :D

First install the prerequisites and required gems as described in this post.

Create a file called config.ru with the following content
run lambda { |env| [ 200, { 'Content-Type'=>'text/plain' }, "Hello World!\n" ] }

Then run warbler like this:
jruby -S warble
... and deploy the resulting war file to tomcat. DONE!

Oh! And in case you were wondering: the performance of this application is just incredible! On a virtual machine with 2 cores at 2.19GHz each and 512MB RAM (Dell D830 laptop) it delivers around 2000 requests per second!

Ruby rocks!

Friday, May 6, 2011

Sinatra - the power is back!

I honestly don't know what I've been doing for the past 5 years. Really. I've been trying to solve simple problems by learning "corporate" bullshit allowing the really good stuff go unnoticed. But that has changed. I'm a new person now. I'm changed, changed forever.

Today I've been working on my json-rest-api plugin to allow for excluding some properties if you really wanted to. Ok I admit, I needed that in the application I'm writing for the corporate. And so I've been browsing, looking, searching because I somehow knew that something is wrong with the world around me. I couldn't quite tell what it was but it felt like a splinter in my mind that I just couldn't get rid of.

I've stumbled upon Graffiti micro-framework for building web applications in Groovy. I was so amazed with the immediate results it gave me that I started digging deeper and deeper into the roots of where this damn thing came from. And so I found Sinatra...

And the world will never be the same...

Sinatra is a micro-framework giving a DSL style to create simple web applications. Since I'm a windows addict (don't shoot me please!) I needed to find something else than shotgun to do the hot reloading of my app. And so I found sinatra/reloader...

And the world will never be the same...

Fortunately Sinatra is not married with any ORM so I could find a tool that's equally simple and does the heavy lifting of moving data from and to the database for me. And so I found DataMapper...

And the world will never be the same...

At this point I'm after re-writing the ihatejsf.com application (34 lines of Ruby code!!!) using Sinatra and DataMapper and after deployment on Heroku. It was an experience I'll never forget. It has changed me forever and ever.

I'm a changed man.