Tropical Software Observations

30 August 2010

Posted by Unknown

at 4:20 PM

0 comments

Labels: , ,

RabbitMQ: PubSub Messaging with Groovy

RabbitMQ typically send "direct" message between the queue and the listeners -- if you have 5 messages put on the queue with 3 listeners, then each of the listener will get one of these messages. However if you need to have all the listeners get the same message, you need to set the exchange to "fanout".

The explanation of using rabbitmq's fanout feature may be well described in the FAQ, but it's not clear in code. So I hope someone will find the below groovy code helpful to see how to use rabbitmq fanout for pubsub topology messaging.

The below code is a basic message publisher to send message to rabbitmq queue. Note the exchange declared as "fanout" exchange. The queue binding may not be useful in fanout use case as all the messages will be send out to all listening consumers.



import com.rabbitmq.client.*


def factory = new ConnectionFactory();
factory.setUsername(username);
factory.setPassword(password);
factory.setVirtualHost("/");
factory.setHost(rabbitmqhost)
factory.setPort(rabbitmqport)
Connection conn = factory.newConnection();
def channel = conn.createChannel()


String exchangeName = "foExchange"
String routingKey = "foo"
String queueName = "fooQueue"


channel.exchangeDeclare(exchangeName, "fanout", true)
channel.queueDeclare(queueName, true, false, false, null);


(1..3).each { n ->
    channel.basicPublish(exchangeName, routingKey,  MessageProperties.PERSISTENT_TEXT_PLAIN, 
                        " (${n}) test testing test [${new Date()}]".getBytes() );
}


channel.close()
conn.close()
System.exit(0)
println " Fin "




Now lets look at the consumer side to consume messages in fanout use case.In a fanout setup, the consumer doesn't have to do anything special. If you don't specify any particular queue name, it will get all messages from the exchange. You can however continue to received message from any particular queue if you bind to it.





String exchangeName = "fooExchange"
String routingKey = "foo"
//String queueName = "fooQueue"


String queueName = channel.queueDeclare().getQueue()
channel.queueBind(queueName, exchangeName, "#");
println " Queue: ${queueName} "


boolean noAck = false;
def consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, noAck, consumer);
boolean running = true


while(running) {


    QueueingConsumer.Delivery delivery;
    try {
        delivery = consumer.nextDelivery();
        println new String(delivery.body)
    } catch (InterruptedException ie) {
        continue;
    }
    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
    
}


27 August 2010

Posted by Isak Rickyanto

at 12:37 PM

5 comments

Labels: , , ,

Initial Thoughts on Padrino, a Fast Ruby Web Framework Based On Sinatra

In search of a Rails alternative in the Ruby world, I found a popular and simple web framework, Sinatra, that was introduced to me by a friend. It is very easy to get started with Sinatra, especially for a simple Hello World kind of web app.

But based on my experience with Rails, Grails, and CakePHP, all web frameworks that help us develop easier and faster with their features, helpers, and also lots of plugins, I admit that I was not that interested in using Sinatra in a real project.

I like Sinatra's simple and minimal concepts, but in the real world we sometimes need more than that. So, although I believe I can build any kind of web application with Sinatra, I feel that sooner or later I will look for helpers, utilities, or plugins that can help me in development.

Then I found Padrino, also introduced to me by my friend, which is a bigger and richer framework than Sinatra in term of features and helpers. It seems like a complete framework but still sticks to Sinatra's core concepts and philosophy, since the developer built this framework as a layer on top of Sinatra while trying to keep it fun and easy. You can find Padrino here: www.padrinorb.com

The things I like best about Padrino:

1. Code Generator - easily generates beautiful admin interfaces with built in authentication.
2. Agnostic Way - gives us options to choose what module or library we want to use, like letting us choose between Active Record, Datamapper, or Sequel for ORM.
3. Fast Performance - Padrino's performance benchmark shows us it is faster than Sinatra itself, which sounds impossible right?

Benchmarks for Padrino vs Merb vs Rails vs Sinatra vs Ramaze:

# Rendering a string inline
Merb 1.1.0 => 1749.97 rps
Padrino 0.9.10 => 1629.15 rps
Sinatra 1.0.0 => 1537.78 rps
Rails 3.beta3 => 381.76 rps
Ramaze 2010.04.04 => 270.08 rps

# Rendering a basic erb template
Merb 1.1.0 => 1490.8 rps
Padrino 0.9.10 => 1416.84 rps
Sinatra 1.0.0 => 1157.89 rps
Rails 3.0.beta3 => 330.58 rps
Ramaze 2010.04.04 => 254.23 rps

# Rendering a simulated simple app
Padrino 0.9.10 => 675.79 rps
Sinatra 1.0.0 => 652.0 rps
Merb 1.1.0 => 642.29 rps
Rails 3.0.beta3 => 201.86 rps
Ramaze 2010.04.04 => 130.62 rps

(copied from http://www.padrinorb.com/blog/padrino-0-9-10-released-built-for-speed)
Get the source code for benchmark from http://github.com/DAddYE/web-frameworks-benchmark

4. Comprehensive Features - Padrino provides us with a lot of features, helpers and libraries that aid us in web development

5. Great Support for Shiny Things like HAML, SAAS, MongoDB

Along with these advantages, I also found some things that need to be improved:

1. Small Community - I hope it will get better in the future (Padrino's Google group only has 122 members). Perhaps it needs more “marketing” to attract newcomers. Open source projects gain trust more easily if they have large and active communities.

2. User Guides - Padrino needs more comprehensive and complete tutorials. For example, if a new user comes to the Padrino site without existing Active Record, Datamapper, or other compatible ORM experience, I believe they will be confused because the documentation does not include those ORMs. I only found a simple active record example in a blog tutorial. I admit there are many external examples covering documentation of these ORMs, but the information is not directly linked/integrated with Padrino. From my experience, I ran into difficulty when trying to build an HTML form with HABTM relation, and it was difficult to find any relevant information about the problem as related to Padrino. Fortunately I had experience with Active Record so finally after struggling for a few hours I found a solution but this might not be the case with someone new to web development and experiencing it for the first time using Padrino.

3. Sample Project, Real Live Projects still rare
In learning, it is easier for me as newcomer to learn from examples so it will be great to see a few sample projects, something more than just a simple blog app. Also I still can't find a list of real live production sites or projects using Padrino. I found only 1-2 sites that use Padrino (1 shopping project and watched.it). There may be many more than that number who already use Padrino, but this information is not well documented. If you are interested, here is a discussion about who is already using Padrino:
http://groups.google.com/group/padrino/browse_thread/thread/d439332aa95227e3/4265f4a2cad796c7

Conclusion:
I believe that if the people behind Padrino keep doing a good job with developing and promoting Padrino, and also take care their community, Padrino will become a great web framework, maybe a better alternative than Rails. If you have experience with Rails and Sinatra, it will a be friendly framework for you to work with.

I would confidently use Padrino for simple applications but personally I feel it will be risky to build a serious application using an open source project without knowing there is more significant community support behind it (please note: I am not saying the Padrino community is not welcoming or responsive).