kdb q - дескриптор не сбрасывается до следующего .z.ts - PullRequest
0 голосов
/ 30 января 2019

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.ts после f.

Как я могу обойти это?Я хочу явно указать серверу очистить дескриптор (то есть все, что находится в буфере, должно быть отправлено клиенту сразу после завершения f)

Спасибо за помощь

1 Ответ

0 голосов
/ 30 января 2019

Функция таймера вызывается через каждые 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}
...