tenticon
tenticon

Reputation: 2923

kdb q - handle is not flushed before next .z.ts

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

Answers (1)

Rahul
Rahul

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

Related Questions