RSS

Tag Archives: zeromq

In defense of dynamic languages

There are a good many truths and there are a better set of likelihoods. Given the current state of dynamic languages today they are less performance than static and functional languages, however, it is also true that dynamic languages are more productive than static and functional languages. (I am not talking about savants)

Don’t optimize your code at the first stage. First make it right, then (if necessary) make it fast (while keeping it right). –erlang programming rules

It is likely that regardless of the size of your project, the size or makeup of your team, or the breakthrough that you think the project represents… that your project is going to have average results at best. The Google’s, FaceBooks and Twitters of the world are extreme edge cases. As proof, look at the iPhone app store. There are over 600,000 apps and only a very small fraction of those apps have the following that Angry Birds does.

So before you go off in a corner reinventing the wheel in your favorite language consider this. WHat is going to be your return on investment? I cannot blame you for learning a new language or tool that would enhance your marketability or even just for hobby sake. But if your intent is to make some money and maybe a little independence they you really need to consider your ROI. And if you’re making money then rewriting your killer app in whatever killer fast programming language is available (and popular) will make make plenty of sense.

This is why I’m hot on python and python’s django, tornadoweb, flask; perl and perl’s mojolicious; ruby and ruby’s sinatra and rails; redis, sqlite, zeromq.

PS: While I’m not a fan of erlang, partly because of what it represents, I really like it’s Programming Rules and Conventions(PRC). By comparison python’s PEP-8 is amateurish. The PRC starts off with ideas like the one quoted above and giving you ideas on how best to approach the problem. This is like python’s PEP-20 but again it’s like signing your name with a crayon instead of a fountain pen.

 
Leave a comment

Posted by on 2012/05/03 in architecture, ProgLang

 

Tags: , , , , , , , , , , , ,

What is so interesting about the Flask microframework?

I get that Flask has a lot of the same design patterns that Ruby’s Sinatra has. I suppose if one used a metadata approach to application construction/deployment that you might be able to basically interchange between them.

I did a search hoping to find out the differences between Flask and Tornado. I was rewarded with a page from the the Flask development doc. The contributor was suggesting that one might link or cascade Flask with either Tornado, Gevent, Gunicorn or some other proxy setup.

While mentioning Tornado the contributor says…

Tornado is an open source version of the scalable, non-blocking web server and tools that power FriendFeed. Because it is non-blocking and uses epoll, it can handle thousands of simultaneous standing connections, which means it is ideal for real-time web services. Integrating this service with Flask is a trivial task:

In the deployment section of the doc Flask makes is clear that the built-in webserver is strictly for development. The reasons are probably very similar to Rails’ webrick but in the case of Flask there are no explanations. Nor is there a recommendation just a list of servers.

I recently deployed a Tornado-ZeroMQ bridge in order to increase the transaction throughput. Sitting in front of the Tornado instance is a traditional webserver like apache, lighttpd, nginx. These webservers are serving static content because that is what they do best and the dynamic requests are passed thru. But why would I deploy lighttpd->tornadoweb->flask? There is plenty of room for improvement here but someone transitioning from sinatra to/from flask could be rewarded.

hello world from their respective websites:
(Flask)

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
  return "Hello World!"

if __name__ == "__main__":
 app.run()

(Sinatra)

require 'sinatra' 
get '/hi' do 
  "Hello World!" 
end
 
Leave a comment

Posted by on 2012/03/22 in Tools, web

 

Tags: , , , , , , , , , ,

Crossroads has forked ZeroMQ

I understand the mission but crossroads has a long way to go. They should not be at version one until most or all of the client libraries fall in line.

I’m all for a more stable source but their major complaint might be better resolved in github rather than a fork.

Good luck either way. I’ll be watching.

 
Leave a comment

Posted by on 2012/03/17 in architecture, Tools

 

Tags: ,

Mongrel2 = mongrel + python

mongrel was originally written for the ruby folk by a programmer named Zed. I cannot speak to how useful it is or was but I remember reading the name a few times and that was about that.

Recently while I was reading up on ZeroMQ I ran into a reference to a framework called Mongrel2. Mongrel 2 was implemented using Python and ZeroMQ. It was also written by Zed.

It uses the single process/thread eventd model to implement the client-side web server. Requests are taken in from inside an IOloop and those messages are forwarded to and through ZeroMQ as quickly as possible. The programmer need only implement a route table and the “handler” (a ZeroMQ worker).

What makes it interesting is that it implements a 1:Many (client to worker ratio). And; it is implemented in a brokerless structure. In a brokered structure a single incoming transaction can yield 4x transactions on the same box and between 6x and 8x if shifting the transaction off of the current cluster. Also, they did not implement a traditional REQ/RSP (request/response) workflow. In fact on the inbound transaction the webserver pushes to the ZMQ’ queue and the worker pulls from the queue.  When the worker has a response it uses a publish/subscribe in order to deliver the response to the awaiting webserver instance.

It would be nice to have a picture to go along with that description but I do not have one.

And now the shortcomings.

  1. While the source code is available the last thing I want to do is instrument all of that code.
  2. ZeroMQ does not have any queue management APIs. So there is no way to know what the TTL for a particular message is… every message must be processed meaning that you can DOS yourself.

There are some APIs in the IOLoop class that could be used:

  • setup all the callback handlers
  • send() the message
  • receive the “sent” trigger
  • wait for the response…
  • if there is a timeout then try to reverse the request and release the client

In one other use-case:

  • setup all the callback handlers
  • send() the message
  • wait for the response…
  • if there is a timeout and the “sent” was never received then the message is queued. abort the request.

In conclusion, while I like many of the design decisions in Mongrel2 and it clearly benefits from being V2, it’s still incomplete in many ways due to ZMQ and not itself.

 
Leave a comment

Posted by on 2011/12/31 in web

 

Tags: , , ,

My New Python Project Setup

[update 2012-01-18] postgres has been updated to 9.1.2; the latest version as of today.

[update 2012-01-17] feel free to ignore my comments about Lua. While Lua might sit in an interesting place between Python and Java in an embedded/scripting place. The fact that lunatic-python does not compile and lupa depends on LuaJIT2 which is compatible with Lua 5.1 and the current Lua version 5.2 was recently released… and the comment from the LuaJIT team about adoption was a little snarky. I gotta think about something else.

[update 2011-12-29] I forgot to add twitter’s bootstrap CSS/JS. I’ll cover that in a future post when I also discuss modern-package-template

It’s pretty simple to set things up. There are some prerequisites and some basic install packages that need root access but the intent is to get the config in userspace as soon as possible. This article covers VM slices at Rackspace using Ubuntu 11.10.

First: Install and update:

  • allocate the OS
  • select the OS and wait for it to complete.  You’re going to receive an email with the root password
  • login, change the root password
  • create an “admin” privileged user (usually my name or “builder”)
  • add this user to the sudo
  • change it’s password
  • edit /etc/ssh/sshd_config and disable root login
  • update the package definitions (apt-get update)
  • upgrade the packages (apt-get upgrade)
  • reboot

Second: Install the required roo packages

  • postfix – when prompted select the default values
    • apt-get -y install postfix
  • apt-get -y install python-setuptools daemontools daemontools-run python-dev mailutils mutt build-essential uuid-dev python-nose vim htop sysstat dstat ifstat screen locate apache2-utils unzip siege python-virtualenv bwm-ng libcairo2-dev libglib2.0-dev libpango1.0-dev libxml2-dev fail2ban openssl libssl-doc openvpn libssl-dev libgcrypt11-dev lighttpd lighttpd-dev libevent-dev libcurl4-openssl-dev  libreadline6-dev beanstalkd tree
  • apt-get install postgresql-9.1 postgresql-client-9.1 postgresql-doc-9.1 postgresql-plperl-9.1 postgresql-plpython-9.1 postgresql-server-dev-9.1
  • easy_install pip
  • easy_install mercurial
  • easy_install pycurl
  • pip install virtualenvwrapper

That’s it, essentially, for the second layer, however, here’s an explanation of the modules from a macro perspective:

  • python-setuptools – make the installer, easy_install, available
  • daemontools daemontools-run – there are so many ways to implement a ‘daemon’ this tools make it simple to make daemon deployment simple
  • python-dev python-nose python-virtualenv – basic prereqs for python development. virtualenv is needed so that packages can be installed in userspace
  • mailutils mutt – generate emails
  • build-essential uuid-dev  - basic developer tools
  • vim screen – editor and console tool
  • htop sysstat dstat ifstat locate unzip bwm-ng – debug /monitoring tools
  • libcairo2-dev libglib2.0-dev libpango1.0-dev libxml2-dev – libs used when rendering usage graphics
  • fail2ban – detect login attempts and put the IP in time-out
  • openssl libssl-doc openvpn libssl-dev libgcrypt11-dev libcurl4-openssl-dev - crypto
  • lighttpd lighttpd-dev – web server that should be in front of the framework
  • libevent-dev – kevent, kpoll libs
  • apache2-utils siege – performance simulation tools
  • beanstalkd – message queue

And finally the third layer, the userspace framework layer. But before you start installing packages you need to create the virtual environment:

  • cd ${HOME}
  • mkdir -p src
  • cd ${HOME}/src
  • virtualenv currentenv
  • . ./currentenv/bin/activate
Now install the third layer.
  • pip install tornado
  • pip install flask
  • pip install flask-rest
  • easy_install pip
  • pip install pycurl
  • pip install simplejson
  • pip install tornado
  • pip install Fabric
  • pip install PasteDeploy
  • pip install PasteScript
  • pip install modern-package-template
  • pip install requests
  • pip install gevent
  • pip install pystache
  • pip install nose
  • pip install redis-py
  • pip install pymongo
  • pip install hoover
  • pip install pyzmq
  • pip install pyyaml
  • pip install beanstalkc
  • pip install django
  • pip install django-redis-cache
  • pip install clint
  • pip install djangorestframework
  • pip install pyparsing
  • pip install flup

I’m hoping that there is a practical use-case for embedding Lua in Python. There are an few interesting projects like lunatic-python and lupa. Normally I would not consider Lua for anything beyond “hello world”, however, the redis team is embedding Lua, it seems like a very lightweight codebase, it can be embedded in just about any language (do a google search).

  • cd ${HOME}
  • mkdir -p tmp
  • cd tmp
  • wget http://www.lua.org/ftp/lua-5.2.0.tar.gz
  • tar zxvf lua-5.2.0.tar.gz
  • cd lua-5.2.0
  • make linux
  • sudo make install

NOTE: the lunatic project does not compile under Lua 5.2. So this thread is postponed for now.

  • pip install lunatic-python

Alternatively I tried [lupa] but that requires LuaJIT 2.0 which is currently in beta (version 9)

  • cd ${HOME}
  • mkdir -p tmp
  • cd tmp
  • wget http://luajit.org/download/LuaJIT-2.0.0-beta9.tar.gz
  • tar zxvf LuaJIT-2.0.0-beta9.tar.gz
  • cd LuaJIT-2.0.0-beta9
  • make
  • sudo make install
  • sudo ldconfig

Then install lupa.

  • pip install lupa
NOTE: hoover is a client library for loggly.com.  You’ll need an account if you want to use this service.

In closing, I would like to include a few more libraries, however, the current version in apt-get is too old. I’d prefer installing them from scratch. They are necessary packages so for the time-being I’m just going to list them. They should be installed when installing the first layer and by the root user (or sudo)

  • ZeroMQ - trivial to build and deploy if you follow the instructions
    • cd /tmp
    • wget http://download.zeromq.org/zeromq-2.1.11.tar.gz
    • tar zxvf zeromq-2.1.11.tar.gz
    • ./configure
    • make
    • make install
    • ldconfig
  • MongoDB – (can actually be installed in userspace)
    • cd /tmp
    • wget http://fastdl.mongodb.org/osx/mongodb-linux-x86_64-2.0.2.tgz
    • mkdir -p ${HOME}/bin
    • cd ${HOME}/bin
    • tar zxvf mongodb-linux-x86_64-2.0.2.tgz
    • sudo mkdir -p /data/db
    • sudo chown `id -u` /data/db
    • ./mongodb-linux-x86_64-2.0.2/bin/mongod
    • … or …
    • cd ${HOME}/bin
    • find ./mongodb-linux-x86_64-2.0.2/bin/ -type f -exec ln -s {} \;
    • ./mongod
  • Redis – trivial to build and deploy if you follow the instructions
    • cd /tmp
    • wget http://redis.googlecode.com/files/redis-2.4.6.tar.gz
    • tar zxvf redis-2.4.6.tar.gz
    • cd redis-2.4.6
    • make
    • make install
  • SQLite – a simple SQL DB
    • cd /tmp
    • wget http://www.sqlite.org/sqlite-autoconf-3070900.tar.gz
    • tar zxvf sqlite-autoconf-3070900.tar.gz
    • cd sqlite-autoconf-3070900
    • ./configure
    • make
    • make install
    • ldconfig
  • ISO8583 – ISO8583 lib

Good luck!

PS: You should consider scripting this installation so that the deploy can be automated.  Specially via Fabris, chef, or puppet.

 
1 Comment

Posted by on 2011/12/30 in architecture, beta

 

Tags: , , , , , , , , , , , ,

TornadoWeb – web scraping, eventd, recursion

I’m working with TornadoWeb and ZeroMQ at the moment and I was having a heck of a time getting things to work correctly. Especially when I was trying to call-out to another webserver and preserve the async-mode in the system. (TornadoWeb provides a basic Asyncronous HTTP Client library)

First of all, some months ago I found a post that wanted me to replace Tornado’s IOLoop with the ZMQ version. They did not state why but they were specific to say that Tornado’s was to be replaced with ZMQ and not the other way around. The code was not very interesting:

# override tornado's ioloop with zmq's
ioloop.IOLoop = zmq.eventloop.ioloop.IOLoop

And while I was researching this project I found that ZMQ provides a method that does the work for you. I reviewed the code and there was nothing special in it. It was pretty much the same code as I had originally implemented. I changed the code to use the new method. Not because they did it better but because I am hoping that this might future proof my project incase there is a change that I cannot account for. So the code now looks like:

# override tornado's ioloop with zmq's
#ioloop.IOLoop = zmq.eventloop.ioloop.IOLoop
zmq.eventloop.ioloop.install()

Hey! Nothing spectacular there. Moving on to the next challenge…

The code I’m currently working on is an admin site. Admin in the sense that only one or two users will actually every use this app and it would be very unlikely that more that one user would be online (even in an emergency). While that is true… the synchronous version of the website did not perform very well. Specially when I was deleting large amounts of data from Redis.

In this particular case I’m trying to implement a “test harness”. While I like nosetests and it works great I need something that is interactive and ubiquitous. In this use-case the user enters the URL for the test-index-page. The page is drawn from a dictionary of testcases. The user clicks on a testcase and it runs to completion… drawing it’s output in the buffer and then going back (recursively) to the admin website and putting in some additional data (a call trace) and appending that to the buffer too. The challenge was several fold. a) the build-in classes were not working asynchronously, b) there were two client calls to make; 1) the authorization 2) the call trace. c) make it all work within the asynchronous framework.

Before I go any further. It works and here is the code. I’m not going to explain it any more than this for now.

# test handler
class TestHandler(tornado.web.RequestHandler):
    """
    """
    def initialize(self):
        self.server       = 'http://myapiserver.local:8882'
        self.adminserver  = 'http://myadminswerver:8881'
        self.path         = 'api1.1'
        super(TestHandler,self).initialize()

    # normally the callback function does not get this decorator, however, this
    # was needed in order to make this work. Notice that this is the second handler
    @asynchronous
    def _handle_request2(self, response):
        """This is the second callback handler.
        """
        if response.error:
            self.write("Error: %s" % (response.error))
        else:
            self.write(response.body)
        # need the self.finish() because the asynchronous decorator
        # disables the auto_finish()
        self.finish()

    # since this is the first
    @asynchronous
    def _handle_request1(self, response):
        """This is the first callback handler.
        """
        if response.error:
            self.write("Error: %s" % (response.error))
        else:
            # write the output to the buffer but since we are not calling
            # finish() the data remains in the buffer.
            self.write(response.body)

            # make the second call and callback to the second handler.
            url = "%s/myfunction_two/" % (self.adminserver)
            request = httpclient.HTTPRequest(url)
            # it is important to replace the io_loop here (also needed to make it work)
            http_client = httpclient.AsyncHTTPClient(io_loop=ioloop.IOLoop.instance())
            # going to callback to the 2nd handler
            http_client.fetch(request, self._handle_request2)    

    @asynchronous
    def _get(self,other=None):
        url = "%s/%s" % (self.server, path or self.path)
        pay = self.path
        request = httpclient.HTTPRequest(url, body=pay, method='POST')
        # it is important to replace the io_loop here (also needed to make it work)
        http_client = httpclient.AsyncHTTPClient(io_loop=ioloop.IOLoop.instance())
        # going to callback to the 1st handler
        http_client.fetch(request, self._handle_request1)    

    # notice that there is NO decorator here. It will be applied when _get() is called.
    def get(self,other=None):
        """display the menu or execute the test
        """
        self.guid = str(uuid.uuid1())
        if not other:
            # display the testcase menu
            for k in testcases.keys():
                self.write('<a href="/t/%s/">%s</a><br>' % (k, k))
            self.finish()
        else:
            self._get(other)

It would have been nice if there had been a “parallel” task execution as the two queries could be executed at the same time because they are unrelated requests. Granted the callback would have to juggle the results in order to get them in the right order and then display them I suppose it might be possible with a single handler if the handler could inspect the data before calling finish(). It’s something worth posting in the future.

I also want to mention that a similar strategy would probably apply to Mojolicious. (assignment for the reader; I home someone will post and link back.)

 
Leave a comment

Posted by on 2011/11/01 in web

 

Tags: , , ,

Message Queues and nothing but Message Queues

[Update 2011.09.21] The ink had hardly dried on this post when I decided to quickly evaluate gearman. It’s immature and direction internally seems dizzy. So pass on this one too.

I’m reading up on MQs again while I’m waiting for a conference call. I do not want to disrupt my code before the demo (rule #1 of demo-club). So I’m making yet another list of all of the MQs out there.

  • ActiveMQ
  • RabbitMQ
  • Amazon SQS
  • Google Queue/Task
  • Gearman
  • ZeroMQ
  • Sparrow
  • Starling
  • Kestrel
  • RestMQ
  • Oracle Advanced MQ
  • IBM Websphere MQ
  • MicrosoftMQ
  • JBoss Messaging
  • Sun Open Message Queue
  • Apache Qpid

There are several ways to compare these MQs. Core source language, client language support, implementation detail, inspiration or initial design, current activity, licensing, cost, deploy OS, performance/TPS, use-cases, dependencies, deep dependencies, mindshare.

So here is that list again.

  • ActiveMQ – apache and meant for Java JMS although there are libs for other languages it really depends on the actual message payload.
  • RabbitMQ – build with erlang, while it works well and is the MQ for ejabberd it’s pretty heavy weight.
  • Amazon SQS – it’s not free or at least cost effective. They have had huge outages. For security reasons this has to be onsite.
  • Google Queue/Task - For security reasons this has to be onsite and only supports java, python and possibly go.
  • Gearman – There is potential here. It seems to have been rewritten in C from perl. It is open source and free to use. They appear to be active and there is a CLI making access easy. This is worth looking into. (the only downside is that it’s written in Java)
  • ZeroMQ – 0mq leaves a lot to the developer or architect to decide and fill in the blanks. My original implementation used beanstalkd and it was razor fast and trivial to implement. 0mq has plenty of gotchas and the burden is on the developer. I’d use it again but it’s not going to be #1.
  • Sparrow - ruby? This is just not going to make the list.
  • Starling – another ruby implementation.
  • Kestrel – argh… this one is implemented in scala. So you get all of the non-functional java components (unverified) and long namespaces.
  • RestMQ – I like the pythonic implementation, however, while twisted is a solid project it appears to be conflicting with my main project based on tornadoweb.
  • Oracle Advanced MQ – not free
  • IBM Websphere MQ – not free
  • MicrosoftMQ – not free
  • JBoss Messaging – too many dependencies. This is akin to J2EE’s JMS. And for that I might as well use ActiveMQ.
  • Sun Open Message Queue – They do not live here any more.
  • Apache Qpid – supports AMPQ and trying to get 100% compliant. I suppose this is interesting in that disparate systems will be able to communicate. Looking at the source tree there is just so much code and since I do not want to dedicate this kind of time to it… I think it’s an easy PASS.
  • beanstalkd – The last release was over a year ago. I’ve posted on their group hoping to get some sort of answer. There has been some activity on their website. The APIs have a TTR novelty API that I like. Specially in my fire and delete application.

One of the novel things about the apache team is that when they acquire a technology it’s long before there is a wrapper around it. For example Apache Camel.

So here is the state of things.

  1. RestMQ – I’m going to continue my attempt to rewrite RestMQ in perl using Mojolicious. If I get some decent results then I’ll publish them/it.
  2. Gearman – deserves some immediate investigation. I’m hoping to make it through the painful documentation.
  3. Beanstalkd – while it has not had much recent action I’m hoping to see some info in my inbox shortly. I like their broker and while they do not specifically support req/resp it’s not really needed and can worked around.
  4. ZeroMQ is just an API. My broker is getting more and more complicated. Message routing is also getting complicated.
 
2 Comments

Posted by on 2011/09/21 in Tools, web

 

Tags: , , , , , , , , , , ,

LevelDB – a key/value database from Google

LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.

LevelDB was release a short time ago and they were quick to provide some benchmarks along with the first release which they say is version 1.1. Since I’m falling in love passionate strong like with Redis more every day… why not see if LevelDB was on the level.

Well,, I’m sure it is, however, there are a great number of CONS for adopting LevelDB:

  • Like ZeroMQ, LevelDB is a library and not a server. Although that could be an exercise left to the reader… as Riak has adapted to this engine.
  • It’s not thread safe so that is an exercise for the reader
  • The most astonishing element of their description is that they support 3 actions: get, set, delete. While that is all you really need to get real work done the left is up to the reader.
  • Since it’s a library and written in ‘C’, unlike ZeroMQ, there are no client modules. It’s C++ all the way.

So compare LevelDB to Redis or any of the other NoSQL databases and you’ll be truly disappointed. In today’s environment you need a lot more checkboxes before you make a switch like this one.

 
Leave a comment

Posted by on 2011/08/03 in database

 

Tags: , ,

All-time low for open source

Please follow my train of thought:

  • java is the now new COBOL
  • I used to like java when it was first released 1.02 was probably the best release albeit not speedy
  • There are so many libraries out there that overlap and intersect that it’s like looking at JCL through a kaleidoscope and I won’t even hint at J2EE
  • There are many alternatives that cover many different languages, python, perl, ruby, go, erlang, haskel, scala, clojure and so on
  • Some of them are clearly better than others… some are just plain stupid
  • I recently endeavored to design a system using python, TornadoWeb, Redis, and ZeroMQ. (simple, easy, fun and productive) The framework is about 3000 LOC and the dependencies are shallow and easy to expand. An alternative to TornadoWeb might be cyclone but it’s harder to build.
  • my next potential project needs to built in java including enough packages to be considered J2EE-light. Everything from Spring to Camel. There has to be a better way.
  • I thought to recommend SkyNet
  • It depends on doozer and go-lang
  • go-lang installs easy enough
  • doozer is crap, builds silently, but the test program does not compile.
  • doozerd is crappier, does not build because the libs to not match the go-libs. Why? fixed-em. I tried to run the test program and it crashed. Same errors.
  • roundup is worse still, there are even fewer docs here. I tried the normal build. FAIL. I tried the git version. Worked but there are no docs for me to test it. And now it’s installed… I hate that. Need a sandbox for the install much like go.
  • So I go back and look at the java packages.
  • they’re not so bad… if the project framework were templated.
  • Yes it is. More dependencies means more maintenance, more regression testing, more reading, harder debugging, more logging, slower transactions.
  • At the very least if I used Grails I’d have a chance to implement a smooth and normal install path. Not the chaos of package de jour.

Meh!  I’ll make it work anyway but it’s not going to be as much fun.

PS: What every happened to COBOL?

 

Tags: , , , , , , , , , , , ,

Chef installation : you gotta be kidding me!

Last night I started working on puppet and things were iffy. At least the server and client installed from their ubuntu packages. Admittedly there were errors in the end but they might have been mine… and there are some compatibility issues that have been documented. So I switched to chef with good intentions.

Before I get to the details… in hindsight I must have been nuts to try chef. My first clue was the list package dependencies; there must have been 50+. What were the designers thinking?

First of all they need a DB and an MQ; and I think I like the idea that they are using packages that exist in the open source environment… but I am amazed that they would use such beheamoths. First of all CouchDB and RabbitMQ both depend on erlang and all those extra packages. When a standard SQL-type DB like SQLite or if they really need a document repo then MongoDB would be fine. At least the packages are small, available in binary form and they have a REST interface that is easy enough to write too. Of course there are so many other DBs that are integrated directly into Ruby or with shallow dependencies.

The same can be said for their choice of MQ. RabbitMQ is the thousand pound gorilla. There are two strong candidates in ZeroMQ and beanstalkd. Both are extremely lightweight to install and deploy. They are fast and reasonably functional.

So even though I have a personal dislike for all things ruby (based on personal experience in the Birmingham Alabama area) it can do the same job that other dynamic and non-dynamic languages can. Performance and some of the edge cases not withstanding… I hate deep dependencies… (same reason I dislike most package managers including maven).

 
Leave a comment

Posted by on 2011/07/22 in database, nosql, ProgLang, Tools

 

Tags: , , , , , , ,

 
One Page Docs

Creating a library one page at a time.

One Page Bugs

Reducing the friction of writing and fixing bugs or features.

Follow

Get every new post delivered to your Inbox.

Join 223 other followers