Bug: cythonized services aren't found
nameko seems unable to find services that are compiled with cython. This doesn't seem to have anything to do with cython code, per se, as the issue arises even with pure python code (compiled with cython), and also it's possible to run cythonized functions, as long as the nameko service class itself is not cythonized. Due to the latter, I can get around the issue, but it does make things a bit messier. (And why am I cythonizing? I've got a few IO services which are the bottlenecks, and cythnoizing greatly speeds things up.)
Steps to reproduce, using the example from http://nameko.readthedocs.io/en/stable/built_in_extensions.html#rpc, with python 3.5 and the latest PyPi versions of all packages:
Files
services.pyx
from nameko.rpc import rpc, RpcProxy
class ServiceY(object):
name = "service_y"
@rpc
def append_identifier(self, value):
return "{}-y".format(value)
class ServiceX(object):
name = "service_x"
y = RpcProxy("service_y")
@rpc
def remote_method(self, value):
res = "{}-x".format(value)
return self.y.append_identifier(res)
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("services.pyx"))
main.py
from nameko.standalone.rpc import ClusterRpcProxy
with ClusterRpcProxy({'AMQP_URI': 'amqp://guest:guest@localhost'}) as cluster_rpc:
print(cluster_rpc.service_x.remote_method("hello"))
Commands
compile and run services
$ python setup.py build_ext --inplace
$ nameko run services:ServiceX services:ServiceY
starting services: service_x, service_y
Connected to amqp://guest:**@127.0.0.1:5672//
use service
$ python main.py
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(cluster_rpc.service_x.remote_method("hello"))
File "/home/kane/smithy/.pyvenv/lib/python3.4/site-packages/nameko/rpc.py", line 351, in __call__
reply = self._call(*args, **kwargs)
File "/home/kane/smithy/.pyvenv/lib/python3.4/site-packages/nameko/rpc.py", line 431, in _call
raise UnknownService(self.service_name)
nameko.exceptions.UnknownService: Unknown service `service_x`
It works perfectly if you just ignore the cython stuff and rename services.pyx to services.py.
i don't know for certain, but i would guess that eventlet isn't compatible with cython, since it can't monkey patch the c code. you might be able to call cythonised code from a pure-python service, but nameko itself, and e.g. the rpc extensions are unlikely to work
Ah, right. I'm certainly no expert (and couldn't find an exact answer) but you look to be right. Also, to clarify, I can run cythonised code from a pure-python service (for my example). If this isn't (?) a reliable option, I wonder if there are other possibilities?
I'll leave this issue open (I'm happy for someone else to close it though), as I suspect mine might (?) be a common enough use case: I've got a few frequently used services that are bottlenecks (in this case, data parsing), and need to run as fast as possible, hence the cythonising.