Giter Club home page Giter Club logo

restmq's Introduction

RESTMQ

Redis based message queue.

Info:See RestMQ website
Info:See my blog <http://blog.7co.cc> for more information.
Author: Gleicon Moraes <http://github.com/gleicon>
Author: Alexandre Fiori

About

RestMQ is a message queue which uses HTTP as transport, JSON to format a minimalist protocol and is organized as REST resources. It stands on the shoulder of giants, built over Python, Twisted, Cyclone (a Tornado implementation over twisted) and Redis.

Redis is more than just a key/value db, and its data types provided support for this project.

Queues are created on the fly, when a message is sent to them. They are simple to use as a curl request can be. HTTP Comet, websockets and server sent events may be used for data streaming.

This release is a cleanup of the original code, that can also be found on github.

Install

$ python setup.py install run with bash start_scripts/restmq_server or taylor your own script. Note that currently restmq is presented as a twisted plugin.

Alternatively you can utilize [Vagrant](https://www.vagrantup.com/) and our [Vagrantfile](Vagrantfile) which will handle installation and configuration of redis and RestMQ.

Another option is to run the project inside a docker container:

` docker build -t restmq . docker run --rm -p 6379:6379 -p 8888:8888 restmq `

It will run restmq, exposing both 8888 (for its http port) and 6379 (for its redis server) to the host environment.

Queue Policy

Every queue is created with a default policy, which is broadcast. It means that each message pushed to a queue will be forwarded to all comet and websocket consumers.

The alternative policy is roundrobin, which will distribute these messages in a round robin fashion to all comet and websocket consumers.

The queue policy won't affect regular GET commands to pop a single message from a queue.

See README.qp for details.

Queue Flow Control

Yes, it does support start and stop. We just need to document it properly.

Example

A http client (curl) post to /queue:

Point your browser to http://localhost:8888/c/test

Run $ curl -d "queue=test&value=foobar" http://localhost:8888/

Your browser is acting as a consumer to the queue. Using json encoded data it's easy to fit the data into a js based app.

Aside from the COMET consumer, there are xmlrpc methods, rest routes and the JSON protocol to manipulate queue items.

COMET consumer

There is a COMET based consumer, which will bind even if the queue doesn't already exists.

The main route is thru /c/<queuename>. It can be tested using curl:

$ curl http://localhost:8888/c/test

In another terminal, run $ curl -d "value=foobar" http://localhost:8888/q/test

This is the basic usage pattern for map/reduce (see examples).

See below on how to purge and disconnect all consumers from a queue, using DELETE.

WebSocket consumer

Now that cyclone has websockets support, check README.websocket to test it.

If you are using a browser or library which already supports websockets, you may take advantage of this interface.

REST services

A queue can be accessed as /q/<queuename>.

GET requests will dequeue an object.

POST requests inserts an object in the queue

DELETE requests will purgue the queue.

The usual pattern is listen in the COMET consumer (/c/<queuename>) and insert new stuff at the REST route (POST /q/<queuename).

JSON Protocol

The HTTP route /queue/<queuename> uses the JSON protocol. Its the same protocol I've implemented for http://jsonqueue.appspot.com.

{
    "cmd": "add",
    "queue": "genesis",
    "value": "abacab"
}

Creates the queue named "genesis" and inserts the string "abacab" as the message.

If we want to take that out of the queue, the payload would be like that:

{
    "cmd": "take",
    "queue": "genesis"
}

The message can be formatted as a json object, so more complex data can be sent. It really mimics some of Amazon SQS workings, because it's a simple queue.

For the first release it has:

  • Select, EPoll or KQueue concurrency (depends on twisted)
  • Persistent storage using Redis
  • Can work on pools, N daemons consuming from the same queues.
  • Small codebase
  • Lightweight
  • Cute ?

Dependencies

  • cyclone: git clone git://github.com/fiorix/cyclone.git

Running

The redis_server script will start the service. It's a bash script used to both configure and run RestMQ. The default version of the wrapper script will run the server in foreground, and log messages will be written to the standard output.

Editing the script is mandatory for configuring RestMQ for production.

$ ./restmq_server --help
Usage: twistd [options] restmq [options]
Options:
      --acl=         acl configuration file for endpoints [default: acl.conf]
      --redis-host=  hostname or ip address of the redis server [default: 127.0.0.1]
      --redis-port=  port number of the redis server [default: 6379]
      --redis-pool=  connection pool size [default: 10]
      --port=        port number to listen on [default: 8888]
      --listen=      interface to listen on [default: 127.0.0.1]
      --version
      --help         Display this help and exit.

Tests

examples/test_rest.sh
examples/test_xmlrpc.py
python examples/test_comet.py
python examples/twitter_trends.py
python examples/test_comet_curl.py
python restmq_engine.py -h

Files

If you're a developer looking for extending RestMQ's functionality, have a look at these files:

Credits

Thanks to (in no particular order):

  • Salvatore Sanfilippo for redis and for NoSQL patterns discussion.
  • Alexandre Fiori for the redis client enhancement and patches.
  • Roberto Gaiser for the collectd daemon
  • Vitor Pellegrino for dockerizing restmq

restmq's People

Contributors

douglascamata avatar dustinwhittle avatar fiorix avatar gleicon avatar philchristensen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restmq's Issues

Error running RESTMQ

I installed RestMQ, getting errors when I try to install it.

Unexpected error while writing cache file
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 614, in parseOptions
usage.Options.parseOptions(self, options)
File "/usr/lib/python2.7/site-packages/twisted/python/usage.py", line 261, in parseOptions
for (cmd, short, parser, doc) in self.subCommands:
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 631, in subCommands
for plug in sorted(plugins, key=attrgetter('tapname')):
File "/usr/lib/python2.7/site-packages/twisted/plugin.py", line 209, in getPlugins
allDropins = getCache(package)
--- ---
File "/usr/lib/python2.7/site-packages/twisted/plugin.py", line 181, in getCache
dropinPath.setContent(pickle.dumps(dropinDotCache))
exceptions.AttributeError: 'ZipPath' object has no attribute 'setContent'
Traceback (most recent call last):
File "/usr/bin/twistd", line 14, in
run()
File "/usr/lib/python2.7/site-packages/twisted/scripts/twistd.py", line 27, in run
app.run(runApp, ServerOptions)
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 652, in run
runApp(config)
File "/usr/lib/python2.7/site-packages/twisted/scripts/twistd.py", line 23, in runApp
_SomeApplicationRunner(config).run()
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 386, in run
self.application = self.createOrGetApplication()
File "/usr/lib/python2.7/site-packages/twisted/application/app.py", line 446, in createOrGetApplication
ser = plg.makeService(self.config.subOptions)
File "build/bdist.linux-x86_64/egg/twisted/plugins/collectd_plugin.py", line 32, in makeService
File "build/bdist.linux-x86_64/egg/restmq/collectd.py", line 133, in init
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 882, in resource_filename
self, resource_name
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 1352, in get_resource_filename
return self._extract_resource(manager, zip_path)
File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 1363, in _extract_resource
zip_stat = self.zipinfo[zip_path]
KeyError: 'restmq/static'

Ruby example incorrect

I have tried implementing the em-http-request poller, but the problem with it, is that if gets data in chunks from the stream, and in case there's a big json object stored in queue, em-http splits it into several chunks, causing JSON parse errors.

I was not able to find receive buffer setting in the gem itself, so I would appreciate if you had any suggestions.

GET only deleting object-reference, not actual object

I'm using restmq as intermediate queue feeding it data from collectd and then popping and formating data and sending to OpenTSDB.

The docs say that a GET on the /q/<queue> route will return and dequeue the object. I see from the raw network traffic that restmq does RPOP on collectd_data:queue and hence removes the reference to the object. It does not however remove the actual object which will live on in memory forever.

I see in the source that the JSON interface has a take command which should GET and DEL the actual object. But I'm only getting 400 errors on the /queue route.
The docs say that the route is /queue/<queue_name>, which is incorrect. The route is /queue and the queue_name should be supplied in the JSON data.

I use this command to try to get the JSON interface to work without success:

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"cmd": "take","queue": "collectd_data"}' http://localhost:8888/queue

GET to dequeue sounds dangerous

As I will be destroying data with a supposedly read-only verb.

Instead, could use a DELETE on a /head URI or something like that.

Getting "Cannot load ACL file" error when trying to start bash script

Followed all install instructions and tried to start bash script "restmq_server" and I get an error "Cannot load ACL file":

Traceback (most recent call last):
File "/usr/bin/twistd", line 5, in
pkg_resources.run_script('Twisted==13.1.0', 'twistd')
File "/usr/lib/python2.6/site-packages/distribute-0.6.49-py2.6.egg/pkg_resources.py", line 507, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.6/site-packages/distribute-0.6.49-py2.6.egg/pkg_resources.py", line 1272, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/EGG-INFO/scripts/twistd", line 14, in
run()
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/twisted/scripts/twistd.py", line 27, in run
app.run(runApp, ServerOptions)
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/twisted/application/app.py", line 652, in run
runApp(config)
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/twisted/scripts/twistd.py", line 23, in runApp
_SomeApplicationRunner(config).run()
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/twisted/application/app.py", line 386, in run
self.application = self.createOrGetApplication()
File "/usr/lib/python2.6/site-packages/Twisted-13.1.0-py2.6-linux-x86_64.egg/twisted/application/app.py", line 446, in createOrGetApplication
ser = plg.makeService(self.config.subOptions)
File "/usr/lib/python2.6/site-packages/RestMQ-1.1-py2.6.egg/twisted/plugins/restmq_plugin.py", line 32, in makeService
options["redis-pool"], options["redis-db"]),
File "/usr/lib/python2.6/site-packages/RestMQ-1.1-py2.6.egg/restmq/web.py", line 666, in init
raise RuntimeError("Cannot load ACL file: %s" % e)
RuntimeError: Cannot load ACL file: [Errno 2] No such file or directory: '/opt/restmq/etc/acl.conf'

Relative path on acl file loading

The file acl.conf is being loaded using relative path, this sucks because I need to place this file in every dir that I need to launch RestMQ. The code should load it using it's absolute path to fix this.

data must be utf-8

after I typed "curl -d "queue=test&msg=foobar" http://localhost:8888/", the following error ocurred:
2012-04-29 01:54:10+0800 [HTTPConnection,0,127.0.0.1] ERROR: oper.queue_add('test', 'None') failed: data must be utf-8

/usr/local/bin/twistd: Unknown command: restmq

./start_scripts/restmq_server

results in output:

/usr/lib/python2.7/dist-packages/zope/init.py:3: UserWarning: Module twisted was already imported from /usr/lib/python2.7/dist-packages/twisted/init.pyc, but /usr/local/lib/python2.7/dist-packages is being added to sys.path
import pkg_resources
Usage: twistd [options]
Options:
--savestats save the Stats object rather than the text output of the
profiler.
-o, --no_save do not save state on shutdown
-e, --encrypted The specified tap/aos file is encrypted.
-n, --nodaemon don't daemonize, don't use default umask of 0077
_cut_
twistd reads a twisted.application.service.Application out of a file and runs
it.
Commands:
dns A domain name server.
ftp An FTP server.
inetd An inetd(8) replacement.
manhole-old An interactive remote debugger service.
portforward A simple port-forwarder.
socks A SOCKSv4 proxy service.
telnet A simple, telnet-based remote debugging service.
web A general-purpose web server which can serve from a
filesystem or application resource.

/usr/local/bin/twistd: Unknown command: restmq

This is on Mint14.

How is this possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.