Concurrence系列-远程调用

 

Concurrence的文档里没有提到这个系列的方法。

我还是从unittest里找到的。

 

经过一番折腾,加上和作者的交流。现在大概能run的起来了。

 

远程调用,要使用concurrence.remote包下的RemoteServer, RemoteTasklet, RemoteClient三个对象。

 

过程是这样,服务端要用RemoteServer来启动一个服务,绑定到一个端口。

 

remote_server = RemoteServer()
server_endpoint = remote_server.serve(('192.168.1.101', 9081))

 

然后就是要在这个服务上注册Task,以供客户端来lookup。

(这里注册的是当前的Task)

 

remote_server.register('testing123', Tasklet.current())

 

 

然后开始一个循环,来监听调用:

for msg, args, kwargs in Tasklet.receive():

...

 

在客户端,首先要连接到服务端:

 

remote_client = RemoteClient()
remote_client.connect(('192.168.1.100', 9081))

 

找到要调用的方法:

remote_task = remote_client.lookup('testing123')

 

调用分为两种,同步,异步。

如果你需要返回数值,同步(阻塞的):

 

print MSG_SUM.call(remote_task)(10, 20, 30)

 

 

如果不需要返回,那就send吧:

MSG_TEST.send(remote_task)(30, 40)

 

 

要注意的:

1. Message对象可能需要放在Module level。这样pickle起来就。。。。

2. 作者说,最好是用stackless,greenlet有时候有问题。比如,我就碰到了_stackless.py的很多异常。

 

 

作者( Henk Punt)原话:

Looks like your using concurrence on top of greenlets and
the bug is coming from the stackless API emulation in _stackless.py
unfortunatly this emulation is not perfect yet, i have already
found/recevied several bugs in it,
so at the moment I guess it would be safer to try and use 'real' stackless....

 

 

 

完整的代码:

 

Server:


from concurrence import unittest, Message, Tasklet, TimeoutError
from concurrence.remote import RemoteServer, RemoteTasklet,
RemoteClient

from concurrence import dispatch

import logging

#we need to define the msgs at the module level
#otherwise the remoting cannot use pickle to serialize them
class MSG_TEST(Message): pass
class MSG_SUM(Message): pass
class MSG_QUIT(Message): pass
class MSG_SLEEP(Message): pass

def server():
       server_endpoint = None
       try:
               remote_server = RemoteServer()
               server_endpoint = remote_server.serve(('192.168.1.101', 9081))

               remote_server.register('testing123', Tasklet.current())

               for msg, args, kwargs in Tasklet.receive():
if msg.match(MSG_SUM):
print 'got msg sum', args 
msg.reply(sum(args))
elif msg.match(MSG_TEST):
print 'get msg test', args
elif msg.match(MSG_QUIT):
print 'get msg quit', args
break
elif msg.match(MSG_SLEEP):
print 'got msg sleep', args
Tasklet.sleep(args[0])
msg.reply(True)
       except Exception:
               logging.exception("")
               self.fail("")
       finally:
               if server_endpoint is not None:
                       server_endpoint.close()

def start():

       server_task = Tasklet.new(server)()

if __name__ == "__main__":
       dispatch(start)



Client:


from concurrence import unittest, Message, Tasklet, TimeoutError
from concurrence.remote import RemoteServer, RemoteTasklet,
RemoteClient

from concurrence import dispatch

import logging

#we need to define the msgs at the module level
#otherwise the remoting cannot use pickle to serialize them
class MSG_TEST(Message): pass
class MSG_SUM(Message): pass
class MSG_QUIT(Message): pass
class MSG_SLEEP(Message): pass

def client():
       try:
               remote_client = RemoteClient()
               remote_client.connect(('192.168.1.100', 9081))
               remote_task = remote_client.lookup('testing123')
               MSG_TEST.send(remote_task)(20, 30)
               MSG_TEST.send(remote_task)(30, 40)
               MSG_TEST.send(remote_task)(20, 30)
               MSG_TEST.send(remote_task)(30, 40)

               MSG_SLEEP.call(remote_task)(1)

               try:
                       MSG_SLEEP.call(remote_task, timeout = 1)(2)
               except TimeoutError:
                       pass #expected

               MSG_QUIT.send(remote_task)()
               Tasklet.sleep(2)
               remote_client.close()
       except Exception:
               logging.exception("")

def start():
       client_task = Tasklet.new(client)()

if __name__ == "__main__":
       dispatch(start)

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值