KxSystems / pyq

PyQ — Python for kdb+
http://code.kx.com/q/interfaces
Apache License 2.0
190 stars 49 forks source link

Asynchronous Call #10

Closed vincentleung58 closed 7 years ago

vincentleung58 commented 7 years ago

I'm building a Python-based feedhandler. I start in a q session with the following

q) \p 5000
q) .u.upd:insert
q) tbl:([] a:`x`y;b:10 20)
q) num::count tbl
q) num
2

I then run the following script from PyQ

>>> from pyq import *
>>> conn = q.hopen("::5000")
>>> aconn = q.neg(conn) # Asynchronous Call Handle
>>> names = ["a","b","c"]
>>> nums = [1,2,3]
>>> k_names = K._ktn(11,0)
>>> k_nums=K._knt(6,0)
>>> for x in range(3):
        K._ja(k_names, names[x])
        K._ja(k_nums, nums[x])
>>> k_inputs = K._knk(2, k_names, k_nums)
>>> conn(K._knk(3, kp(".u.upd"), K._ks("tbl"), k_inputs))

This successfully add the records into the host environment table "tbl".

q) num
5

If I run the asynchronous call handle, however

>>> aconn(K._knk(3, kp(".u.upd"), K._ks("tbl"), k_inputs))

The table is not updated.

q) num
5

If I run the synchronous call again,

q) num
11

It seems that PyQ is caching my asynchronous call somewhere. Am I doing something wrong?

abalkin commented 7 years ago

When pyq is running in Python REPL mode (started using the pyq executable), it blocks kdb+ event loop that is responsible for dispatching asynchronous messages. If you want to use asynchronous calls, you need to call Python from a regular kdb+ instance as follows:

q)p)h = q.hopen('::5000')
q)p)h.neg(('.u.upd', 'tbl', (["a","b","c"], [1,2,3])))

Please also note that you should avoid using low level methods that start with an underscore directly. As shown above, you can rely on PyQ to automatically convert Python objects to K instances when they are passed to the handle.