Sometimes you don’t need a long post to explain something relatively complicated.
KDB/Q has something called inter-process communcation (IPC) it allows two different independent KDB/Q processes to communicate. This is built-in so we don’t need to dig deep.
Usually every result in KDB/Q returns synchronously, meaning a verb[noun] will immediately be processed and no other work can get done during this time.
However, in general it is much more useful to allow to processes to talk asynchronously, like email as opposed to a phone call. IE get it done when you can please.
KDB/Q provides such a construct, but it’s still a bit tricky. So here is a version that works.
Start a KDB session with the -P or run \P in the session followed by a port number (5000 is the convention). This session is now listening on that number.
In a different terminal start a session and create the handle that will talk to that listener. Assume we are listening on port 5001, we can use either the hostname or ipaddress, if we leave it blank it will assume localhost.
h: hopen `:hostname:port
If we use neg[h] “something that will run” it will send it asynchronously, but we won’t get a response with the result of what happened. So…
I made a very simple utility that lets the process you send to reply asynchronously with a result and that variable will get set.
async:{[h;v;n;r] neg[h] ({neg[.z.w] (x set y)}[r;v[n]])}
The verb takes a handle (h), a verb (v), a noun (n) and a result symbol (r). It uses the handle to send an asynchronous request. The request asks the other process to apply the verb to the noun and send back the result and set it to the result symbol.
Here is a really simple example:
q)async[h;{x*x};4;`test] q)test 16
We can also project this verb so that it creates a verb that has an (i)mplicit handle and result.
iasync:async[h;;`result]
iasync [v; n]
That’s it. Enjoy.
UPDATE: I have found a more useful async is one that allows passing in an arbitrary function. This allows us to use the words set to perform that task done here.
the new async looks like this:
async:{[q;cb] neg[.z.w] (cb,value q)}
It simply says place the query into a list of it’s own and the cb into a list of it’s own. the callback will be called with the value of the query evaluated on the service.
For example:
neg[h] (async;({0N!x+x};2);(set;`a))
Will set `a on your service to the value of the query in this case 4. and display 4 on the service. We can also define a function on our service that takes some number of arguments fill them in now and have the function be called with the result when the callback is executed.
f:{0N!2+x+y} q)neg[3i] (async;({0N!x+x};2);(`f;3)) 7