Reputation: 2923
A q server has some expensive operation scheduled every second
.z.ts:{0N!"Working...",string .z.P;{1000000?100;} each til 1000}
\t 1000
and exposes a function f:{[n]{0N!"Called f...";100000000?100} each til n}
to a client. Both .z.ts
and f
take longer than 1 second to run on my machine.
When I call the function f
in the client q session
hh:`:localhost:7000::;
hh(`f;3);
0N!"DONE";
the expected behavior in time is:
| server executes .z.ts
|
| client calls f on server
|
| server returns .z.ts
| server executes f (client request)
|
| server returns f
| server sends result of f to client on handle
| server executes .z.ts
|
What's actually happening
| server executes .z.ts
|
| client calls f on server
|
| server returns .z.ts
| server executes f (client request)
|
| server returns f ---- same as before until here
| server executes .z.ts ---- instead of sending result of f to client!!
|
| server returns .z.ts
| server sends result of f to client
|
So I don't see "DONE" on the client session before the the server has executed .z.ts
again after f
.
How can I work around this? I want to tell the server explicitly to flush the handle (i.e. anything on the buffer should be sent to the client immediately after f has finished)
Thanks for the help
Upvotes: 2
Views: 578
Reputation: 3969
Timer function gets invoked after every n milliseconds (n set by \t). If your function takes longer than 'n' milliseconds then kdb will invoke timer function immediately after the completion of other function and kdb will queue the client data(function reply to the client) in user space.
You could see the pending message queue for each handle using .z.W[].
One workaround for this is to flush all the data for all handles as the first step in a timer function.
One option is to use sync request to wait for confirmation from the remote end. This will also block your process until it gets the reply from the remote end.
q) .z.ts:{(key .z.W[])@\:""; 0N!"Working...",string .z.P;{1000000?100;} each til 1000}
Other option is to use an async call which will block until data has been written to the socket.
q) .z.ts:{(neg@'key .z.W[])@\:(::);0N!.z.W[];0N!"Working...",string .z.P;{1000000?100;} each til 1000}
Upvotes: 1