def handle(self): logger.info("=== socket opened for client ===") channel = _channel_id_new() sock = self.request chinfo = dict(sock=sock) NvimHandler.channel_sockets[channel] = chinfo try: f = SocketToStream(sock) unpacker = msgpack.Unpacker(f) for unpacked in unpacker: logger.info("unpacked: %s", unpacked) # response format: # - msg[0]: 1 # - msg[1]: the request id # - msg[2]: error(if any), format: [code,str] # - msg[3]: result(if not errored) if int(unpacked[0]) == 1: unpacked = neovim_rpc_protocol.from_client(unpacked) reqid = int(unpacked[1]) rspid, vimsock = chinfo[reqid] err = unpacked[2] result = unpacked[3] # VIM fails to parse response when there a sleep in neovim # client. I cannot figure out why. Use global responses to # workaround this issue. responses[rspid] = [err, result] content = [reqid, ''] tosend = json.dumps(content) # vimsock.send vimsock.send(tosend.encode('utf-8')) chinfo.pop(reqid) continue request_queue.put((f,channel,unpacked)) # notify vim in order to process request in main thread, and # avoiding the stupid json protocol VimHandler.notify() logger.info('channel %s closed.', channel) except: logger.exception('unpacker failed.') finally: try: NvimHandler.channel_sockets.pop(channel) sock.close() except: pass
def handle(self): logger.info("=== socket opened for client ===") channel = _channel_id_new() sock = self.request chinfo = dict(sock=sock) NvimHandler.channel_sockets[channel] = chinfo try: f = SocketToStream(sock) unpacker = msgpack.Unpacker(f) for unpacked in unpacker: logger.info("unpacked: %s", unpacked) # response format: # - msg[0]: 1 # - msg[1]: the request id # - msg[2]: error(if any), format: [code,str] # - msg[3]: result(if not errored) if int(unpacked[0]) == 1: unpacked = neovim_rpc_protocol.from_client(unpacked) reqid = int(unpacked[1]) rspid, vimsock = chinfo[reqid] err = unpacked[2] result = unpacked[3] # VIM fails to parse response when there a sleep in neovim # client. I cannot figure out why. Use global responses to # workaround this issue. responses[rspid] = [err, result] content = [reqid, ''] tosend = json.dumps(content) # vimsock.send vimsock.send(tosend.encode('utf-8')) chinfo.pop(reqid) continue request_queue.put((f, channel, unpacked)) # notify vim in order to process request in main thread, and # avoiding the stupid json protocol VimHandler.notify() logger.info('channel %s closed.', channel) except Exception: logger.exception('unpacker failed.') finally: try: NvimHandler.channel_sockets.pop(channel) sock.close() except Exception: pass
def process_pending_requests(): logger.info("process_pending_requests") while True: item = None try: item = request_queue.get(False) f, channel, msg = item msg = neovim_rpc_protocol.from_client(msg) logger.info("get msg from channel [%s]: %s", channel, msg) # request format: # - msg[0] type, which is 0 # - msg[1] request id # - msg[2] method # - msg[3] arguments # notification format: # - msg[0] type, which is 2 # - msg[1] method # - msg[2] arguments if msg[0] == 0: #request req_typed, req_id, method, args = msg try: err = None result = _process_request(channel, method, args) except Exception as ex: logger.exception("process failed: %s", ex) # error uccor err = [1, str(ex)] result = None result = [1, req_id, err, result] logger.info("sending result: %s", result) packed = msgpack.packb(neovim_rpc_protocol.to_client(result)) f.write(packed) logger.info("sent") if msg[0] == 2: # notification req_typed, method, args = msg try: result = _process_request(channel, method, args) logger.info('notification process result: [%s]', result) except Exception as ex: logger.exception("process failed: %s", ex) except QueueEmpty as em: pass except Exception as ex: logger.exception("exception during process: %s", ex) finally: if item: request_queue.task_done() else: # item==None means the queue is empty break
def process_pending_requests(): logger.info("process_pending_requests") while True: item = None try: item = request_queue.get(False) f, channel, msg = item msg = neovim_rpc_protocol.from_client(msg) logger.info("get msg from channel [%s]: %s", channel, msg) # request format: # - msg[0] type, which is 0 # - msg[1] request id # - msg[2] method # - msg[3] arguments # notification format: # - msg[0] type, which is 2 # - msg[1] method # - msg[2] arguments if msg[0] == 0: # request req_typed, req_id, method, args = msg try: err = None result = _process_request(channel, method, args) except Exception as ex: logger.exception("process failed: %s", ex) # error uccor err = [1, str(ex)] result = None result = [1, req_id, err, result] logger.info("sending result: %s", result) packed = msgpack.packb(neovim_rpc_protocol.to_client(result)) f.write(packed) logger.info("sent") if msg[0] == 2: # notification req_typed, method, args = msg try: result = _process_request(channel, method, args) logger.info('notification process result: [%s]', result) except Exception as ex: logger.exception("process failed: %s", ex) except QueueEmpty: pass except Exception as ex: logger.exception("exception during process: %s", ex) finally: if item: request_queue.task_done() else: # item==None means the queue is empty break