首页 > 解决方案 > kdb q - 在下一个 .z.ts 之前不刷新句柄

问题描述

q 服务器每秒安排一些昂贵的操作

.z.ts:{0N!"Working...",string .z.P;{1000000?100;} each til 1000}
\t 1000

并向客户端公开功能f:{[n]{0N!"Called f...";100000000?100} each til n}。两者都.z.ts需要f超过 1 秒才能在我的机器上运行。

f当我在客户端 q 会话中调用该函数时

hh:`:localhost:7000::;
hh(`f;3);
0N!"DONE";

预期的及时行为是:

| 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 
|

实际发生了什么

| 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  
|

因此,在服务器.z.tsf.

我该如何解决这个问题?我想明确告诉服务器刷新句柄(即缓冲区上的任何内容都应在 f 完成后立即发送给客户端)

谢谢您的帮助

标签: kdb

解决方案


每 n 毫秒(n 由 \t 设置)调用计时器函数。如果您的函数花费的时间超过“n”毫秒,那么 kdb 将在其他函数完成后立即调用计时器函数,并且 kdb 将在用户空间中排队客户端数据(函数回复客户端)。

您可以使用 .zW[] 查看每个句柄的待处理消息队列。

一种解决方法是刷新所有句柄的所有数据,作为计时器函数的第一步。

一种选择是使用同步请求来等待来自远程端的确认。这也将阻止您的进程,直到它从远程端获得回复。

q) .z.ts:{(key .z.W[])@\:""; 0N!"Working...",string .z.P;{1000000?100;} each til 1000}

其他选项是使用异步调用,该调用将阻塞,直到数据写入套接字。

q) .z.ts:{(neg@'key .z.W[])@\:(::);0N!.z.W[];0N!"Working...",string .z.P;{1000000?100;} each til 1000}

推荐阅读