def __init__(self, service_stub_class, host, port): self.service_stub_class = service_stub_class self.host = host self.port = port self.channel = RpcChannel(host=self.host, port=self.port) self.service = self.service_stub_class(self.channel) for method in service_stub_class.GetDescriptor().methods: rpc = lambda request, timeout=None, callback=None: self.call( service_stub_class.__dict__[method.name], request, timeout, callback) self.__dict__[method.name] = rpc
class RpcService(object): def __init__(self, service_stub_class, host, port): self.service_stub_class = service_stub_class self.host = host self.port = port self.channel = RpcChannel(host=self.host, port=self.port) self.service = self.service_stub_class(self.channel) for method in service_stub_class.GetDescriptor().methods: rpc = lambda request, timeout=None, callback=None: self.call( service_stub_class.__dict__[method.name], request, timeout, callback) self.__dict__[method.name] = rpc def call(self, rpc, request, timeout=None, callback=None): result = {'done': False, 'reply': None} def async_callback(request, reply): result['reply'] = reply result['done'] = True result['err_msg'] = '' result['success'] = True if callback is None: rpc_callback = async_callback else: if ((not callable(callback) and (callback.__class__.__dict__.get('run') == None or callback.run.func_code.co_argcount < 2)) or (callable(callback) and callback.func_code.co_argcount < 2)): raise Exception('callback must be callable') rpc_callback = callback controller = self.channel.new_controller() rpc_thread = RpcThread(rpc, self.service, controller, request, rpc_callback) rpc_thread.start() if rpc_callback == callback: return else: if timeout is None: timeout = 100 end = time.time() + (timeout / 1000) while time.time() < end not result['done']: if controller.failed(): if isinstance(controller.error, str): raise Exception(controller.error) else: raise controller.error if time.time() >= end and not result['done']: raise RpcError('request timed out') return result['reply']