Mercurial > louis > mq > lightsd
changeset 412:65b0dc335243
unfuck lightsc.py
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Fri, 01 Jan 2016 13:15:41 +0100 |
parents | dadccf117097 |
children | 9067c2da9572 |
files | fix_lightscpy_readloop.patch series |
diffstat | 2 files changed, 76 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fix_lightscpy_readloop.patch Fri Jan 01 13:15:41 2016 +0100 @@ -0,0 +1,75 @@ +# HG changeset patch +# Parent c8614ad2dc1133c8d50e974afd66d84231b41c78 +FIx lightsc.py's read loop + +We do need to do non-blocking IO in case the last received buffer comes +back full in this case doing another read would block the whole thing. + +diff --git a/examples/lightsc.py b/examples/lightsc.py +--- a/examples/lightsc.py ++++ b/examples/lightsc.py +@@ -30,9 +30,11 @@ + + import argparse + import contextlib ++import fcntl + import json + import locale + import os ++import select + import socket + import subprocess + import sys +@@ -42,6 +44,9 @@ + + class LightsClient: + ++ READ_SIZE = 4096 ++ ENCODING = "utf-8" ++ + def __init__(self, url): + self.url = url + +@@ -56,6 +61,7 @@ + else: + raise ValueError("Unsupported url {}".format(url)) + ++ fcntl.fcntl(self._socket, fcntl.F_SETFL, os.O_NONBLOCK) + self._pipeline = [] + self._batch = False + +@@ -75,17 +81,27 @@ + } + + def _execute_payload(self, payload): +- print(payload) +- self._socket.send(json.dumps(payload).encode("utf-8")) +- # FIXME: proper read loop +- response = self._socket.recv(64 * 1024).decode("utf-8") ++ select.select([], [self._socket], []) ++ payload = json.dumps(payload).encode(self.ENCODING, "surrogateescape") ++ self._socket.send(payload) ++ ++ response = bytearray() ++ select.select([self._socket], [], []) ++ while True: ++ try: ++ part = self._socket.recv(self.READ_SIZE) ++ except BlockingIOError: ++ break ++ if not part: ++ break ++ response += part ++ ++ response = response.decode(self.ENCODING, "surrogateescape") + try: +- response = json.loads(response) ++ return json.loads(response) + except Exception: + print("received invalid json: {}".format(response)) + +- return response +- + def _jsonrpc_call(self, method, params): + payload = self._make_payload(method, params) + if self._batch:
--- a/series Thu Dec 31 15:34:49 2015 +0100 +++ b/series Fri Jan 01 13:15:41 2016 +0100 @@ -3,6 +3,7 @@ network_discovery.patch dont_use_ev_assign.patch add_power_transition.patch +fix_lightscpy_readloop.patch open_gateway_on_any_bulb_response.patch #+future make_gateway_write_callbacks_low_priority.patch #+future use_echo_request_reply_to_measure_latency.patch #+future