def _on_message(self, args): msg = Message.initialize(args) if msg is None: return try: if msg.id == message.RPC_CHUNK: #PROTOCOL_LIST.index("rpc::chunk"): self._subscribers[msg.session][0](unpackb(msg.data)) elif msg.id == message.RPC_CHOKE: #PROTOCOL_LIST.index("rpc::choke"): self._subscribers.pop(msg.session, None) elif msg.id == message.RPC_ERROR: #PROTOCOL_LIST.index("rpc::error"): self._subscribers[msg.session][1](ServiceError(self.servicename, msg.message, msg.code)) except Exception as err: print "Exception in _on_message: %s" % str(err)
def _on_message(self, args): msg = Message.initialize(args) if msg is None: return try: if msg.id == message.RPC_CHUNK: self._subscribers[msg.session].callback(unpackb(msg.data)) elif msg.id == message.RPC_CHOKE: future = self._subscribers.pop(msg.session, None) if future is not None: future.close() elif msg.id == message.RPC_ERROR: self._subscribers[msg.session].error(ServiceError(self.servicename, msg.message, msg.code)) except Exception as err: print "Exception in _on_message: %s" % str(err)
def on_message(self, args): msg = Message.initialize(args) if msg is None: return elif msg.id == message.RPC_INVOKE: request = Request() stream = Stream(msg.session, self, msg.event) try: self.sandbox.invoke(msg.event, request, stream) self.sessions[msg.session] = request except (ImportError, SyntaxError) as err: stream.error(2, "unrecoverable error: %s " % str(err)) self.terminate(1, "Bad code") except Exception as err: self._logger.error("On invoke error: %s" % err) traceback.print_stack() stream.error(1, "Invocation error") elif msg.id == message.RPC_CHUNK: self._logger.debug("Receive chunk: %d" % msg.session) try: _session = self.sessions[msg.session] _session.push(msg.data) except Exception as err: self._logger.error("On push error: %s" % str(err)) self.terminate(1, "Push error: %s" % str(err)) return elif msg.id == message.RPC_CHOKE: self._logger.debug("Receive choke: %d" % msg.session) _session = self.sessions.get(msg.session, None) if _session is not None: _session.close() self.sessions.pop(msg.session) elif msg.id == message.RPC_HEARTBEAT: self._logger.debug("Receive heartbeat. Stop disown timer") self.disown_timer.stop() elif msg.id == message.RPC_TERMINATE: self._logger.debug("Receive terminate. %s, %s" % (msg.reason, msg.message)) self.terminate(msg.reason, msg.message) elif msg.id == message.RPC_ERROR: _session = self.sessions.get(msg.session, None) if _session is not None: _session.error(RequestError(msg.message))
def _get_api(self, name, endpoint, port): locator_pipe = socket.socket(socket.AF_INET, socket.SOCK_STREAM) locator_pipe.settimeout(4.0) locator_pipe.connect((endpoint, port)) locator_pipe.send(packb([0, 1, [name]])) u = Unpacker() msg = None while msg is None: response = locator_pipe.recv(80960) u.feed(response) msg = Message.initialize(u.next()) locator_pipe.close() if msg.id == message.RPC_CHUNK: #PROTOCOL_LIST.index("rpc::chunk"): return unpackb(msg.data) if msg.id == message.RPC_ERROR: #PROTOCOL_LIST.index("rpc::error"): raise Exception(msg.message)
def _on_message(self, args): msg = Message.initialize(args) if msg is None: return try: if msg.id == message.RPC_CHUNK: self._subscribers[msg.session].trigger(msgpack.unpackb(msg.data)) elif msg.id == message.RPC_CHOKE: future = self._subscribers.pop(msg.session, None) assert future is not None, 'one of subscribers has suddenly disappeared' if future is not None: future.close() elif msg.id == message.RPC_ERROR: self._subscribers[msg.session].error(ServiceError(self.name, msg.message, msg.code)) except Exception as err: log.warning('"_on_message" method has caught an error - %s', err) raise err
def perform_sync(self, method, *args, **kwargs): """Performs synchronous method invocation via direct socket usage without the participation of the event loop. Returns generator of chunks. :param method: method name. :param args: method arguments. :param kwargs: method keyword arguments. You can specify `timeout` keyword to set socket timeout. .. note:: Left for backward compatibility, tests and other stuff. Indiscriminate using of this method can lead to the summoning of Satan. .. warning:: Do not mix synchronous and asynchronous usage of service! """ if not self.isConnected(): raise IllegalStateError('service "{0}" is not connected'.format( self.name)) if method not in self.api: raise ValueError('service "{0}" has no method named "{1}"'.format( self.name, method)) timeout = kwargs.get('timeout', None) if timeout is not None and timeout <= 0: raise ValueError('timeout must be positive number') with scope.socket.timeout(self._pipe.sock, timeout) as sock: self._session += 1 sock.send(msgpack.dumps([self.api[method], self._session, args])) unpacker = msgpack.Unpacker() error = None while True: data = sock.recv(4096) unpacker.feed(data) for chunk in unpacker: msg = Message.initialize(chunk) if msg is None: continue if msg.id == message.RPC_CHUNK: yield msgpack.loads(msg.data) elif msg.id == message.RPC_CHOKE: raise error or StopIteration elif msg.id == message.RPC_ERROR: error = ServiceError(self.name, msg.message, msg.code)
def _get_api(self, name, endpoint, port): try: locator_pipe = socket.socket(socket.AF_INET, socket.SOCK_STREAM) locator_pipe.settimeout(1.0) locator_pipe.connect((endpoint, port)) locator_pipe.send(msgpack.packb([0, 1, [name]])) u = msgpack.Unpacker() msg = None while msg is None: response = locator_pipe.recv(80960) u.feed(response) msg = Message.initialize(u.next()) except Exception as err: raise LocatorResolveError(name, endpoint, port, str(err)) finally: locator_pipe.close() if msg.id == message.RPC_CHUNK: return msgpack.unpackb(msg.data) if msg.id == message.RPC_ERROR: raise Exception(msg.message)
def _on_message(self, args): msg = Message.initialize(args) if msg is None: return try: if msg.id == message.RPC_CHUNK: self._subscribers[msg.session].trigger( msgpack.unpackb(msg.data)) elif msg.id == message.RPC_CHOKE: future = self._subscribers.pop(msg.session, None) assert future is not None, 'one of subscribers has suddenly disappeared' if future is not None: future.close() elif msg.id == message.RPC_ERROR: self._subscribers[msg.session].error( ServiceError(self.name, msg.message, msg.code)) except Exception as err: log.warning('"_on_message" method has caught an error - %s', err) raise err
def perform_sync(self, method, *args, **kwargs): """Performs synchronous method invocation via direct socket usage without the participation of the event loop. Returns generator of chunks. :param method: method name. :param args: method arguments. :param kwargs: method keyword arguments. You can specify `timeout` keyword to set socket timeout. .. note:: Left for backward compatibility, tests and other stuff. Indiscriminate using of this method can lead to the summoning of Satan. .. warning:: Do not mix synchronous and asynchronous usage of service! """ if not self.isConnected(): raise IllegalStateError('service "{0}" is not connected'.format(self.name)) if method not in self.api: raise ValueError('service "{0}" has no method named "{1}"'.format(self.name, method)) timeout = kwargs.get('timeout', None) if timeout is not None and timeout <= 0: raise ValueError('timeout must be positive number') with scope.socket.timeout(self._pipe.sock, timeout) as sock: self._session += 1 sock.send(msgpack.dumps([self.api[method], self._session, args])) unpacker = msgpack.Unpacker() error = None while True: data = sock.recv(4096) unpacker.feed(data) for chunk in unpacker: msg = Message.initialize(chunk) if msg is None: continue if msg.id == message.RPC_CHUNK: yield msgpack.loads(msg.data) elif msg.id == message.RPC_CHOKE: raise error or StopIteration elif msg.id == message.RPC_ERROR: error = ServiceError(self.name, msg.message, msg.code)
def perform_sync(self, method, *args, **kwargs): """ Do not use the service synchronously after treatment to him asynchronously! Use for these purposes the other instance of the service! """ timeout = kwargs.get("timeout", 5) # Get number of current method try: number = (_num for _num, _name in self._service_api.iteritems() if _name == method).next() except StopIteration as err: raise ServiceError(self.servicename, "method %s is not available" % method, -100) try: # DO IT SYNC self.pipe.settimeout(timeout) self.pipe.writeall(packb([number, self._counter, args])) self._counter += 1 u = Unpacker() msg = None # If we receive rpc::error, put ServiceError here, # and raise this error instead of StopIteration on rpc::choke, # because after rpc::error we always receive choke. _error = None while True: response = self.pipe.recv(4096) u.feed(response) for _data in u: msg = Message.initialize(_data) if msg is None: continue if msg.id == message.RPC_CHUNK: yield unpackb(msg.data) elif msg.id == message.RPC_CHOKE: raise _error or StopIteration elif msg.id == message.RPC_ERROR: _error = ServiceError(self.servicename, msg.message, msg.code) finally: self.pipe.settimeout(0) # return to non-blocking mode
def terminate(self, reason, msg): self.w_stream.write(Message(message.RPC_TERMINATE, 0, reason, msg).pack()) self.loop.stop() exit(1)
def _send_handshake(self): self.w_stream.write(Message(message.RPC_HANDSHAKE, 0, self.id).pack())
def _send_heartbeat(self): self.disown_timer.start() self._logger.debug("Send heartbeat. Start disown timer") self.w_stream.write(Message(message.RPC_HEARTBEAT, 0).pack())
def send_choke(self, session): self.w_stream.write(Message(message.RPC_CHOKE, session).pack())
def send_chunk(self, session, data): self.w_stream.write(Message(message.RPC_CHUNK, session, data).pack())
def send_error(self, session, code, msg): self.w_stream.write(Message(message.RPC_ERROR, session, code, msg).pack())