Skip to main content

Yarr ain't RPC, Ritchie!

A simple RPC implementation using a binary serialization protocol. It supports the basic built-in types, numpy arrays work if available on both client and server. Hence, yarr is well equipped to efficiently handle large binary booty.

A friend asked me about RPC and large binary data in python. It sounded like a fun exercise so I charged forth. I choose to write my own serialization protocol to have more control and a bit more security than pickle. I also ran my benchmarks which pickle serialization and surprisingly yarr is not that slow. Lists and dict take the biggest hit, being ~ 2x slower compared to pickle.

Example

# server
yarr.yarr(('localhost', 8000), [print])
# client
yarr.call(('localhost', 8000), 'print', 'Ahoy Lads!')

Features

Compared to other RPC frameworks yarr has better support for native python types. It's speed depends on the connection. On localhost it appears to be 2-10 times faster than the other frameworks. Over LAN it's comparable to jsonrpc2-zeromq. Over internet the ZeroMQ based frameworks are twice as fast, but yarr is still on par with xmlrpc.

Here is a table comparing it to other RPC frameworks. Partial support is marked with p, usually due to type decay. The speed value is based on the benchmarks below. Feel free to add more.

yarr xmlrpc rpyc jr2-zmq spyne 0rpc
speed 1.0 0.6 0.04 0.9 0.3 0.6
dependencies 0 0 1 3 1 5
recursion - - x - - -
bool x x x x x x
int x x x x x x
int64 x - x x x x
bignum x - x x - -
float x x x x x x
complex x - x - - -
str x x x x x x
pep383 x - - x - -
dict x p x p x x
tupledict x - x - p -
list x x x x p x
tuple x p x p x p
set x - x - - -
bytes x p x - x x
ndarray x - x - - -

Xmlrpc is part of python's stdlib. Good enough for simple use-cases.

Rpyc is glacially slow but has almost perfect type support. Surprisingly it stumbles over pep 383. It's also one of the few frameworks that can handle recursion.

Jsonrpc2-zeromq has decent speed, though it is limited by it's protocol. There is no direct support for binary data. The base64 workaround works but impacts speed.

Spyne is a big project and can do a lot more than pure RPC. For this test MessagePack and ZeroMQ were used.

Zerorpc performance is below jsonrpc2-zeromq, which was unexpected given it's choice of protocols. A dict containing tuple keys crashes the server.

Benchmarks

The values below are in calls per second. This test was run over LAN with a server ping of 0.2 ms. The most recent framework versions (May 2020) were used. When running this benchmark over internet with a ping of 25 ms, yarr performance is roughly half of jsonrpc2-zeromq.

yarr xmlrpc rpyc jr2-zmq spyne 0rpc
none 1291 746 56 1225 457 800
bool 1254 746 54 1253 450 774
int 1250 740 49 1263 448 769
int64 1238 - 47 1188 450 765
bignum 1205 - 49 1165 - -
float 1211 750 52 1223 448 765
complex 1236 - 54 - - -
str 1204 770 54 1131 449 740
pep383 1236 - - 1134 - -
dict 1214 741 54 1040 447 757
list 1183 743 56 1141 449 759
tuple 1186 714 63 1142 448 778
set 1214 - 49 - - -
frozenset 1189 - 54 - - -
bytes 785 504 46 484 349 533
bytearray 780 502 60 481 350 534
ndarray 765 - 19 - - -

Protocol

The main design goals were simplicity and performance. There is no clever encoding scheme like MessagePack. Data is basically just dumped into the TCP socket without any transformations. Values are transferred as little endian, there really is no point in using network byte order these days.

In some cases messages can actually be bigger than in json, for example when it contains many short strings. However if the total size stays below the MTU there is be no big performance hit. I tried adding zlib compression and a persistent connection, but that did not have a big impact and made everything more complicated.

Bugs

  • Not enough pirate-speak in documentation.
  • Malicious data can cause crash.
  • Recursive containers cause crash.

License

Do What The Fuck You Want To Public License

Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.

Release files for yarr 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for yarr 0.9.0
File Interpreter ABI Platform
yarr-0.9.0-py3-none-any.whl Python 3 none any Details

Release files / yarr-0.9.0-py3-none-any.whl

Download URL yarr-0.9.0-py3-none-any.whl
Size 5.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fba4dca55f26ecdb7634d6417da20d0befcdefa216e1750006e4f0fd40bc0898
BLAKE2b-256 checksum
How to use checksums
19d5adcca763018e852668642e7bb2c0ebf9f805fcb749bf32213d7d17ab70f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/2.0.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.8.2

Release history Release notifications | RSS feed

This release

0.9.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page