NAME AtomMQ - An atompub server that supports the message queue/bus model. VERSION version 0.0301 SYNOPSIS #!/usr/bin/perl use AtomMQ; my $db_info = { dsn => 'dbi:SQLite:dbname=/path/to/foo.db' }; my $server = AtomMQ->new(feed => 'MyCoolFeed', db_info => $db_info); $server->run; DESCRIPTION AtomMQ is an atompub server that supports the message queue/bus model. Throughout this document, I will use the term message when refering to an atom feed entry, since the point of this module is to use atompub for messaging. AtomMQ extends Inoue's Atompub::Server which extends Miyagawa's XML::Atom::Server. Can you feel the love already? To get started, just copy the code from the "SYNOPSIS" to a file. You now have a shiny new atompub server with a feed named MyCoolFeed. You can configure your web server to run it via CGI or as a mod_perl handler. My recommendation is to run it in a PSGI environment. See the "PSGI" section for directions. To create more feeds, just copy that file and change 'MyCoolFeed' to 'MyOtherFeed'. To publish a message to AtomMQ, make a HTTP POST request: $ curl -d ' allo
an important message
' http://localhost/cgi-bin/mycoolfeed To retrieve messages, make a HTTP GET request: $ curl http://localhost/cgi-bin/mycoolfeed That will get all the messages since the feed was created. Lets say you are running a client that polls the feed and processes messages. If this client dies, you will not want it to process all the messages again when it comes back up. So clients are responsible for maintaining and persisting the id of the last message they processed. This allows a client to request only messages that came after the message with the given id. They can do this by passing a Xlastid header: $ curl -H 'Xlastid: 42' http://localhost/cgi-bin/mycoolfeed That will return only messages that came after the message that had id 42. METHODS new Arguments: $feed, $db_info, $auto_create_db This is the AtomMQ constructor. The required arguments are $feed and $db_info. $feed is the name of the feed. $db_info is a hashref containing the database connection info as described in "connect_info" in DBIx::Class::Storage::DBI. It must at least contain a dsn entry. $auto_create_db defaults to 1. Set it to 0 if you don't want AtomMQ to attempt to create the db table for you. You can leave it set to 1 even if the db table already exists. Setting it to 0 improves performance slightly. See "DATABASE" for more info. Example: my $server = AtomMQ->new(feed => 'MyCoolFeed', db_info => { dsn => 'dbi:SQLite:dbname=/path/to/foo.db', user => 'joe', password => 'momma', }); run Arguments: None Call this method to start the server. DATABASE AtomMQ depends on a database to store its data. The db_info you pass to the constructor must point to a database which you have write privileges to. Only one table named atommq_entry is required. This table will be created automagically for you if it doesn't already exist. Of course for that to work, you will need create table privileges. You can also create the table yourself if you like. Here is an example sql command for creating the table in sqlite: CREATE TABLE atommq_entry ( id INTEGER PRIMARY KEY AUTOINCREMENT, feed TEXT NOT NULL, title TEXT NOT NULL, content TEXT NOT NULL ); The feed, title and content columns can be of type TEXT or VARCHAR and can be any size you want. All databases supported by DBIx::Class are supported, which are most major databases including postgresql, sqlite, mysql and oracle. PSGI If you have the need for speed, then this section is for you. AtomMQ can be run in a persistent PSGI environment via Plack. This is the recommended way to run AtomMQ, but it takes slightly more work. You will need to have Plack and CGI::Emulate::PSGI installed. Copy the following to mycoolfeed.fcgi: #!/usr/bin/perl use AtomMQ; use CGI::Emulate::PSGI; my $app = CGI::Emulate::PSGI->handler(sub { my $db_info = { dsn => 'dbi:SQLite:dbname=/path/to/foo.db' }; my $server = AtomMQ->new(feed => 'MyCoolFeed', db_info => $db_info); $server->run }); Then you can run: plackup -p 5000 mycoolfeed.fcgi Now AtomMQ is running on port 5000 via the HTTP::Server::PSGI web server. If you want to run in a FastCGI environment using your favorite web server, then you can run: plackup -s FCGI --listen /tmp/fcgi.sock mycoolfeed.fcgi Then configure your web server accordingly. Here is an example lighttpd configuration: fastcgi.server += ( ".fcgi" => (( "socket" => "/tmp/fcgi.sock" )) ) MOTIVATION I am a big fan of messaging systems because they make it so easy to create scalable systems. Existing message brokers are great for creating message queues. But once a consumer reads a message off of a queue, it is gone. I needed a system to publish events such that multiple heterogeneous services could subscribe to them. So I really needed a message bus, not a message queue. I know for example I could have used something called topics in ActiveMQ, but they are extremely flakey in my experience. Actually, I have found ActiveMQ to be broken in general. An instance I manage has to be restarted at least twice a week. AtomMQ on the other hand will be extremely stable, because it is so simple. It is in essence just an interface to a database. As long as your database and web server are up, AtomMQ will be there for you. She will not let you down. And there are all sorts of ways to add redundancy to databases and web heads. Another advantage of using AtomMQ is that atompub is an RFC standard. Everyone already has a client for it, their browser. Aren't standards great! By the way, if you just need message queues, try POE::Component::MessageQueue. It rocks. If you need a message bus, give AtomMQ a shot. AUTHOR Naveed Massjouni COPYRIGHT AND LICENSE This software is copyright (c) 2010 by Naveed Massjouni. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.