aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArksine <arksine.code@gmail.com>2020-08-08 15:04:55 -0400
committerKevinOConnor <kevin@koconnor.net>2020-08-11 10:47:04 -0400
commitbf221d5e26814055f654e0f3144f79af3954e5d4 (patch)
treeee202d1853fb88f8fe3f5cdab37e9f6214f45b50
parent4dcf494b9725bd3cc3d2d59d9855f5afca460f7b (diff)
downloadkutter-bf221d5e26814055f654e0f3144f79af3954e5d4.tar.gz
kutter-bf221d5e26814055f654e0f3144f79af3954e5d4.tar.xz
kutter-bf221d5e26814055f654e0f3144f79af3954e5d4.zip
webhooks: Implement a send buffer for socket writes
This prevents ClientConnection.send() from blocking, removing the possibility that callers become reentrant. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
-rw-r--r--klippy/webhooks.py54
1 files changed, 29 insertions, 25 deletions
diff --git a/klippy/webhooks.py b/klippy/webhooks.py
index 9f4fa5bf..97a4c45d 100644
--- a/klippy/webhooks.py
+++ b/klippy/webhooks.py
@@ -158,8 +158,8 @@ class ClientConnection:
self.sock = sock
self.fd_handle = self.reactor.register_fd(
self.sock.fileno(), self.process_received)
- self.partial_data = ""
- self.mutex = self.reactor.mutex()
+ self.partial_data = self.send_buffer = ""
+ self.is_sending_data = False
logging.info(
"webhooks: New connection established")
@@ -222,30 +222,34 @@ class ClientConnection:
self.send({'method': "response", 'params': result})
def send(self, data):
- with self.mutex:
- retries = 10
- data = json.dumps(data) + "\x03"
- while data:
- try:
- sent = self.sock.send(data)
- except socket.error as e:
- if e.errno == errno.EBADF or e.errno == errno.EPIPE \
- or not retries:
- sent = 0
- else:
- retries -= 1
- waketime = self.reactor.monotonic() + .001
- self.reactor.pause(waketime)
- continue
- retries = 10
- if sent > 0:
- data = data[sent:]
+ self.send_buffer += json.dumps(data) + "\x03"
+ if not self.is_sending_data:
+ self.is_sending_data = True
+ self.reactor.register_callback(self._do_send)
+
+ def _do_send(self, eventtime):
+ retries = 10
+ while self.send_buffer:
+ try:
+ sent = self.sock.send(self.send_buffer)
+ except socket.error as e:
+ if e.errno == errno.EBADF or e.errno == errno.EPIPE \
+ or not retries:
+ sent = 0
else:
- logging.info(
- "webhooks: Error sending server data,"
- " closing socket")
- self.close()
- break
+ retries -= 1
+ waketime = self.reactor.monotonic() + .001
+ self.reactor.pause(waketime)
+ continue
+ retries = 10
+ if sent > 0:
+ self.send_buffer = self.send_buffer[sent:]
+ else:
+ logging.info(
+ "webhooks: Error sending server data, closing socket")
+ self.close()
+ break
+ self.is_sending_data = False
class WebHooks:
def __init__(self, printer):