|
| 1 | +zerorpc |
| 2 | +======= |
| 3 | + |
| 4 | +zerorpc is a flexible RPC implementation based on zeromq and messagepack. |
| 5 | +Service APIs exposed with zerorpc are called "zeroservices". |
| 6 | + |
| 7 | +zerorpc comes with a convenient script, "zerorpc-client", allowing to: |
| 8 | + |
| 9 | +* expose Python modules without modifying a single line of code, |
| 10 | +* call those modules remotely through the command line. |
| 11 | + |
| 12 | + |
| 13 | +Create a server with a one-liner |
| 14 | +-------------------------------- |
| 15 | + |
| 16 | +Let's see zerorpc in action with a simple example. In a first terminal, |
| 17 | +we will expose the Python "time" module:: |
| 18 | + |
| 19 | + $ zerorpc-client --server --bind tcp://0:1234 time |
| 20 | + |
| 21 | +.. note:: |
| 22 | + The bind address uses the zeromq address format. You are not limited |
| 23 | + to TCP transport: you could as well specify ipc:///tmp/time to use |
| 24 | + host-local sockets, for instance. "tcp://0:1234" is a short-hand to |
| 25 | + "tcp://0.0.0.0:1234" and means "listen on TCP port 1234, accepting |
| 26 | + connections on all IP addresses". |
| 27 | + |
| 28 | + |
| 29 | +Call the server from the command-line |
| 30 | +------------------------------------- |
| 31 | + |
| 32 | +Now, in another terminal, call the exposed module:: |
| 33 | + |
| 34 | + $ zerorpc-client --client --connect tcp://0:1234 strftime %Y/%m/%d |
| 35 | + Connecting to "tcp://0:1234" |
| 36 | + "2011/03/07" |
| 37 | + |
| 38 | +Since the client usecase is the most common one, "--client" is the default |
| 39 | +parameter, and you can remove it safely:: |
| 40 | + |
| 41 | + $ zerorpc-client --connect tcp://0:1234 strftime %Y/%m/%d |
| 42 | + Connecting to "tcp://0:1234" |
| 43 | + "2011/03/07" |
| 44 | + |
| 45 | +Moreover, since the most common usecase is to *connect* (as opposed to *bind*) |
| 46 | +you can also omit "--connect":: |
| 47 | + |
| 48 | + $ zerorpc-client tcp://0:1234 strftime %Y/%m/%d |
| 49 | + Connecting to "tcp://0:1234" |
| 50 | + "2011/03/07" |
| 51 | + |
| 52 | + |
| 53 | +See remote service documentation |
| 54 | +-------------------------------- |
| 55 | + |
| 56 | +You can introspect the remote service; it happens automatically if you don't |
| 57 | +specify the name of the function you want to call:: |
| 58 | + |
| 59 | + $ zerorpc-client tcp://0:1234 |
| 60 | + Connecting to "tcp://0:1234" |
| 61 | + tzset tzset(zone) |
| 62 | + ctime ctime(seconds) -> string |
| 63 | + clock clock() -> floating point number |
| 64 | + struct_time <undocumented> |
| 65 | + time time() -> floating point number |
| 66 | + strptime strptime(string, format) -> struct_time |
| 67 | + gmtime gmtime([seconds]) -> (tm_year, tm_mon, tm_mday, tm_hour, tm_min, |
| 68 | + mktime mktime(tuple) -> floating point number |
| 69 | + sleep sleep(seconds) |
| 70 | + asctime asctime([tuple]) -> string |
| 71 | + strftime strftime(format[, tuple]) -> string |
| 72 | + localtime localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min, |
| 73 | + |
| 74 | + |
| 75 | +Specifying non-string arguments |
| 76 | +------------------------------- |
| 77 | + |
| 78 | +Now, see what happens if we try to call a function expecting a non-string |
| 79 | +argument:: |
| 80 | + |
| 81 | + $ zerorpc-client tcp://0:1234 sleep 3 |
| 82 | + Connecting to "tcp://0:1234" |
| 83 | + Traceback (most recent call last): |
| 84 | + [...] |
| 85 | + TypeError: a float is required |
| 86 | + |
| 87 | +That's because all command-line arguments are handled as strings. Don't worry, |
| 88 | +we can specify any kind of argument using JSON encoding:: |
| 89 | + |
| 90 | + $ zerorpc-client --json tcp://0:1234 sleep 3 |
| 91 | + Connecting to "tcp://0:1234" |
| 92 | + [wait for 3 seconds...] |
| 93 | + null |
| 94 | + |
| 95 | + |
| 96 | +zeroworkers: reversing bind and connect |
| 97 | +--------------------------------------- |
| 98 | + |
| 99 | +Sometimes, you don't want your client to connect to the server; you want |
| 100 | +your server to act as a kind of worker, and connect to a hub or queue which |
| 101 | +will dispatch requests. You can achieve this by swapping "--bind" and |
| 102 | +"--connect":: |
| 103 | + |
| 104 | + $ zerorpc-client --bind tcp://0:1234 localtime |
| 105 | + |
| 106 | +We now have "something" wanting to call the "localtime" function, and waiting |
| 107 | +for a worker to connect to it. Let's start the worker:: |
| 108 | + |
| 109 | + $ zerorpc-client --server tcp://0:1234 time |
| 110 | + |
| 111 | +The worker will connect to the listening client and ask him "what should I |
| 112 | +do?"; the client will send the "localtime" function call; the worker will |
| 113 | +execute it and return the result. The first program will display the |
| 114 | +local time and exit. The worker will remain running. |
| 115 | + |
| 116 | + |
| 117 | +Listening on multiple addresses |
| 118 | +------------------------------- |
| 119 | + |
| 120 | +What if you want to run the same server on multiple addresses? Just repeat |
| 121 | +the "--bind" option:: |
| 122 | + |
| 123 | + $ zerorpc-client --server --bind tcp://0:1234 --bind ipc:///tmp/time time |
| 124 | + |
| 125 | +You can then connect to it using either "zerorpc-client tcp://0:1234" or |
| 126 | +"zerorpc-client ipc:///tmp/time". |
| 127 | + |
| 128 | +Wait, there is more! You can even mix "--bind" and "--connect". That means |
| 129 | +that your server will wait for requests on a given address, *and* connect |
| 130 | +as a worker on another. Likewise, you can specify "--connect" multiple times, |
| 131 | +so your worker will connect to multiple queues. If a queue is not running, |
| 132 | +it won't affect the worker (that's the magic of zeromq). |
| 133 | + |
| 134 | +.. warning:: A client should probably not connect to multiple addresses! |
| 135 | + |
| 136 | + Almost all other scenarios will work; but if you ask a client to connect |
| 137 | + to multiple addresses, and at least one of them has no server at the end, |
| 138 | + the client will ultimately block. A client can, however, bind multiple |
| 139 | + addresses, and will dispatch requests to available workers. If you want |
| 140 | + to connect to multiple remote servers for high availability purposes, |
| 141 | + you insert something like HAProxy in the middle. |
0 commit comments