kore

a fork of the worlds most advanced web framework
Log | Files | Refs | README | LICENSE

commit 1ebd82969c6400e054d0927a55c92a593518383c
parent f4cd70956b754c98a256ce918545df6d398f7167
Author: Joris Vink <joris@coders.se>
Date:   Tue, 26 Feb 2019 15:22:55 +0100

Add timeout support to proc.recv()

Diffstat:
Mexamples/python-async/src/async_process.py | 13++++++++++---
Msrc/python.c | 22+++++++++++++++++++---
2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/examples/python-async/src/async_process.py b/examples/python-async/src/async_process.py @@ -41,9 +41,16 @@ async def async_proc(req): # Read until EOF (None is returned) while True: - chunk = await proc.recv(1024) - if chunk is None: - break + try: + # Read from the process, with an optional 1 second timeout. + # The recv() call will throw a TimeoutError exception if + # the timeout has elapsed before any data was read. + chunk = await proc.recv(1024, 1000) + if chunk is None: + break + except TimeoutError as e: + print("recv() timed out: %s" % e) + continue stdout += chunk.decode() # Reap the process. diff --git a/src/python.c b/src/python.c @@ -2574,17 +2574,33 @@ pyproc_reap(struct pyproc *proc, PyObject *args) static PyObject * pyproc_recv(struct pyproc *proc, PyObject *args) { - Py_ssize_t len; + Py_ssize_t len; + struct pysocket_op *op; + PyObject *obj; + int timeo; + + timeo = -1; if (proc->out == NULL) { PyErr_SetString(PyExc_RuntimeError, "stdout closed"); return (NULL); } - if (!PyArg_ParseTuple(args, "n", &len)) + if (!PyArg_ParseTuple(args, "n|i", &len, &timeo)) + return (NULL); + + obj = pysocket_op_create(proc->out, PYSOCKET_TYPE_RECV, NULL, len); + if (obj == NULL) return (NULL); - return (pysocket_op_create(proc->out, PYSOCKET_TYPE_RECV, NULL, len)); + op = (struct pysocket_op *)obj; + + if (timeo != -1) { + op->data.timer = kore_timer_add(pysocket_op_timeout, + timeo, op, KORE_TIMER_ONESHOT); + } + + return (obj); } static PyObject *