I am trying to understand how nameko works for basic RPC. I am looking to define microservices in separate files and being able to run them from command shell. With this structure service2 is not being able to invoke service1's RPC method. What is missing to get this working?
I have the following file structure:
-rwxrwxr-x 1 user user 240 Dec 15 01:49 nameko.sh*
-rw-rw-r-- 1 user user 251 Dec 15 01:46 service1.py
-rw-rw-r-- 1 user user 305 Dec 15 01:47 service2.py
Content of files are:
$ cat nameko.sh
#!/bin/bash
/usr/local/bin/nameko run service1:Microservice1 &
nameko_id=$!
echo 'Microservice 1 PID: ' $nameko_id
/usr/local/bin/nameko run service2:Microservice2 &
nameko_id=$!
echo 'Microservice 2 PID: ' $nameko_id
wait 2> /dev/null
$ cat service1.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice1(object):
name = "microservice1"
@rpc
def hello(self):
print 'Microservice1 hello method invoked'
return True
$ cat service2.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
name = "microservice2"
microservice1 = RpcProxy('microservice1')
microservice1.hello()
@rpc
def hello(self):
print 'Microservice2 hello method invoked'
return True
And I am not being able to understand how to invoke hello method in Microservice 1 from Microservice 2:
$ ./nameko.sh
Microservice 1 PID: 14782
Microservice 2 PID: 14783
Traceback (most recent call last):
File "/usr/local/bin/nameko", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/dist-packages/nameko/cli/main.py", line 66, in main
args.main(args)
File "/usr/local/lib/python2.7/dist-packages/nameko/cli/commands.py", line 85, in main
starting services: microservice1
main(args)
File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 179, in main
import_service(path)
File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 46, in import_service
__import__(module_name)
File "./service2.py", line 5, in <module>
class Microservice2(object):
File "./service2.py", line 11, in Microservice2
microservice1.hello()
AttributeError: 'RpcProxy' object has no attribute 'hello'
Connected to amqp://guest:**@127.0.0.1:5672//
But invoking nameko shell and running rpc method from microservice1 works:
Broker: pyamqp://guest:guest@localhost
>>> n.rpc.microservice1.hello()
True
Added information
Following Matt's answer I have edited service2.py as follows:
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
name = "microservice2"
@rpc
def toctoc(self):
print 'Microservice2 called hello method from Microservice1'
m1 = RpcProxy('microservice1')
m1.hello()
return True
Now both services run, But still does not work, when I run a namejo shell and invoke toctoc method from Microservice2:
$ nameko shell
Nameko Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] shell on linux2
Broker: pyamqp://guest:guest@localhost
>>> n.rpc.microservice2.toctoc()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 374, in
__call__
return reply.result()
File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 332, in
result
raise deserialize(error)
RemoteError: AttributeError 'RpcProxy' object has no attribute 'hello'
>>>
Last working code
With the help provided in the answers, a working version of this would be (in case it clarifies/helps others):
$ cat nameko.sh
#!/bin/bash
/usr/local/bin/nameko run service1:Microservice1 &
nameko_id=$!
echo 'Microservice 1 PID: ' $nameko_id
/usr/local/bin/nameko run service2:Microservice2 &
nameko_id=$!
echo 'Microservice 2 PID: ' $nameko_id
wait 2> /dev/null
$ cat service1.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice1(object):
name = "microservice1"
@rpc
def hello(self):
print 'Microservice1 hello method invoked'
return True
$ cat service2.py
# -*- coding: utf-8 -*-
from nameko.rpc import rpc, RpcProxy
class Microservice2(object):
name = "microservice2"
microservice1 = RpcProxy('microservice1')
@rpc
def remote_hello(self):
print 'Microservice2 invokes hello method from Microservice1'
self.microservice1.hello()
return True
there's an example of service-to-service rpc in the docs