Service があるとします。
import rpyc
class MyService(rpyc.Service):
my_dict = {}
def exposed_put(self, key, val):
MyService.my_dict[key] = val
def exposed_get(self, key):
return MyService.my_dict[key]
def exposed_delete(self, key):
del MyService.my_dict[key]
ここで、ThreadedServer で実行されている Service を開始します。
from rpyc.utils.server import ThreadedServer
server = ThreadedServer(MyService, port=8000)
server.start()
同じマシンの別のプロセスで、サーバーへの新しい接続を開きます。
import rpyc
c = rpyc.connect('localhost', 8000)
...しかし、接続のルートにアクセスする前に、サーバープロセスの制御端末で Ctrl-Z などの理由でサーバープロセスが停止します。今、次の方法でルートにアクセスしようとすると:
c.root
... Python がハングします。クライアント側で Ctrl-C を実行すると、次のようになります。
In [31]: c.root
^C---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
<ipython-input-31-856a441cc51a> in <module>()
----> 1 c.root
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/protocol.pyc in root(self)
465 """Fetches the root object (service) of the other party"""
466 if self._remote_root is None:
--> 467 self._remote_root = self.sync_request(consts.HANDLE_GETROOT)
468 return self._remote_root
469
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/protocol.pyc in sync_request(self, handler, *args)
436 seq = self._send_request(handler, args)
437 while seq not in self._sync_replies:
--> 438 self.serve(0.1)
439 isexc, obj = self._sync_replies.pop(seq)
440 if isexc:
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/protocol.pyc in serve(self, timeout)
385 otherwise.
386 """
--> 387 data = self._recv(timeout, wait_for_lock = True)
388 if not data:
389 return False
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/protocol.pyc in _recv(self, timeout, wait_for_lock)
342 return None
343 try:
--> 344 if self._channel.poll(timeout):
345 data = self._channel.recv()
346 else:
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/channel.pyc in poll(self, timeout)
41 def poll(self, timeout):
42 """polls the underlying steam for data, waiting up to *timeout* seconds"""
---> 43 return self.stream.poll(timeout)
44 def recv(self):
45 """Receives the next packet (or *frame*) from the underlying stream.
/home/mack/anaconda/lib/python2.7/site-packages/rpyc/core/stream.pyc in poll(self, timeout)
39 while True:
40 try:
---> 41 rl, _, _ = select([self], [], [], timeout)
42 except select_error as ex:
43 if ex[0] == errno.EINTR:
KeyboardInterrupt:
そのため、サーバー プロセスが停止していても接続されている (基になるソケットがまだ開いている) 場合、Stream.pollへの呼び出しは無限ループで終了するようです。これは Stream の実装では予期しないケースであると考えるのは正しいですか? バージョン 3.3.0 を使用しています。このケースを検出し、クライアントのハングを回避するにはどうすればよいですか?