exxeleron / qPython

interprocess communication between Python and kdb+
http://www.devnet.de
Apache License 2.0
152 stars 89 forks source link

Buffer getting replayed somewhere? #32

Closed fermionportal closed 8 years ago

fermionportal commented 8 years ago

I'm not clear about what exactly causes this but this is how to reproduce: When executing a query via QConnection.sync(), if it gets interrupted (e.g. via ctrl+c), and if you then run another query, the QConnection handle will return the results for the previous query. example:

qc = qconnection.QConnection(host, port=port, username=username) qc.open() res1 = qc('select * from trade where sid=1', pandas=True) res2 = qc('select * from trade where sid=2', pandas=True) (interrupt with ctrl+c)

then run again: res1 = qc('select * from trade where sid=1', pandas=True) res2 = qc('select * from trade where sid=2', pandas=True)

res1 will have the results for res2 OR res2 will have results for res1, or both

this is true for qpython version '1.1.0b3' and pandas version '0.16.2' running on linux

if you do qc.close(), qc.open() before each call to sync(), the problem disappears.

fermionportal commented 8 years ago

Re-initiating the qc._reader to QReader() and qc._writer before each call instead of qc.close() and qc.open() does not solve the issue. Doing self.open() doesn't solve it either, you really need self.close() and self.open() in the sync() call of QConnection. So perhaps the socket stream is not getting reset properly.

fermionportal commented 8 years ago

OK the data from previous call may be buffered inside and can be flushed out in the qc._reader._stream.flush() and can then be read.

I believe that the sync/async functions should first check if there's anything available in the _stream and flush it out before performing the read; or have hooks in the QReader read() functions to make sure the buffers are cleared if interrupted.

This is a bit beyond my skills so I trust someone in the know will do a fix.

thanks

maciejlach commented 8 years ago

Sorry for late answer. I haven't find means in socket library to easily discard buffered data on incoming connection (which would be required to perform a reset).

I would suggest to use a Twisted as a framework for building up a network layer and use qpython to serialize/deserialize IPC stream. Please refer to this sample integration.