Всегда используйте neg [.z.w], чтобы все сообщения были асинхронными? - PullRequest
0 голосов
/ 13 сентября 2018

Рассмотрим следующее определение на сервере:

f:{show "Received ",string x; neg[.z.w] (`mycallback; x+1)}

на стороне клиента:

q)mycallback:{show "Returned ",string x;}
q)neg[h] (`f; 42)
q)"Returned 43"

В q for motrtals подсказка гласит:

При выполнении асинхронного обмена сообщениями всегда используйте neg [.z.w], чтобы что все сообщения асинхронны. В противном случае вы получите тупик поскольку каждый процесс ожидает другого.

поэтому я изменяю определение на сервере как:

f:{show "Received ",string x; .z.w (`mycallback; x+1)}

все идет хорошо, и я не видел тупиков.

Может ли кто-нибудь дать мне пример, показывающий, почему я всегда должен использовать neg[.z.w]?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Ответ Джо охватывает почти все, но в вашем конкретном примере тупик возникает, если клиент вызывает

h (`f; 42)

Клиент ожидает ответа от сервера перед обработкой следующего запроса, но сервер такжеожидание ответа от клиента, прежде чем он завершит запрос клиента.

0 голосов
/ 13 сентября 2018

Если я понимаю, что вы правильно задали вопрос, я думаю, что вы спрашиваете, как работают сообщения синхронизации и асинхронности. Проблема с примером, который вы предоставили, состоит в том, что x + 1 - очень простой запрос, который можно оценить почти мгновенно. Для более наглядного примера рассмотрите возможность изменения этого режима на бездействие (или более напряженный расчет, например, запрос большой базы данных).

На вашей стороне сервера определите:

f:{show "Received ",string x;system "sleep 10"; neg[.z.w] (`mycallback; x+1)}

Затем на стороне клиента вы можете отправить синхронный запрос:

h(`f; 42)

несколько раз. После этого вы увидите, что на стороне клиента больше нет приглашения q, так как он должен ждать ответа. Эти запросы могут быть поставлены в очередь и, таким образом, блокировать как клиента, так и сервер на значительное время.

В качестве альтернативы, если вам нужно позвонить:

(neg h)(`f; 42)

на стороне клиента. Вы увидите, что приглашение q остается, так как клиент не ожидает ответа. Это асинхронный вызов.

Теперь, в своей функции на стороне сервера, вы рассматриваете использование .z.w или neg .z.w. Это следует точно тому же принципу, однако с точки зрения сервера. Если ответ на запрос достаточно велик, обмен сообщениями может занять значительное время. Следовательно, используя neg этот ответ можно отправить асинхронно, чтобы сервер не блокировался во время этого процесса.

ПРИМЕЧАНИЕ. Если вы работаете на компьютере с Windows, вам нужно будет отключить режим сна для тайм-аута или, возможно, цикла while, если вы следуете моим примерам.

Обновление: я полагаю, что одним из способов вызвать такую ​​тупиковую ситуацию было бы наличие двух зависимых процессов, пытающихся синхронно вызывать друг друга. Например:

q)\p 10002
q)h:hopen 10003
q)g:{h (`f1;`)}
q)h (`f;`)' 

с одной стороны и

q)\p 10003
q)h:hopen 10002
q)f:{h (`g;`)}
q)f1:{show "test"}

с другой. Это приведет к зависанию обоих процессов и, следовательно, к показу теста.

...