box.session.push()
-
box.session.
push
(message[, sync])¶ Создание внеполосного сообщения. Под внеполосным мы понимаем дополнительное сообщение, которое дополняет то, что отправляется в сети по обычным каналам. Хотя
box.session.push()
можно вызвать в любое время, на практике эта функция используется в сетях, настроенных с помощью модуля net.box, и вызывается сервером (на «удаленной системе с базой данных», если использовать нашу терминологию для net.box), а у клиента есть возможность принимать такие сообщения.Функция возвращает ошибку, если сессия была прервана.
Параметры: - message (
any-Lua-type
) – что отправляется - sync (
int
) – необязательный аргумент, указывающий на сессию. Этот аргумент берётся из предшествующего вызова box.session.sync(). Если аргумент опущен, применяется значение по умолчанию — текущее значениеbox.session.sync()
. Аргумент признан устаревшим в версии Tarantool 2.4.2, а начиная с версии 2.5.1 его использование приводит к ошибке.
тип возвращаемого значения: {nil, ошибка} или true:
- Если результатом будет ошибка, то вернется
nil
вместе с объектом ошибки. - Если результатом будет не ошибка, то вернется логическое значение
true
(правда). - When the return is
true
, the message has gone to the network buffer as a packet with a different header code so the client can distinguish from an ordinary Okay response.
Единственная задача сервера – вызвать
box.session.push()
, поскольку нет автоматического механизма, который показал бы, что сообщение получено.Задача клиента заключается в том, чтобы проверять наличие таких сообщений после отправки чего-либо на сервер. Основные клиентские методы – conn:call, conn:eval, conn:select, conn:insert, conn:replace, conn:update, conn:upsert, delete – могут привести к отправке такого сообщения сервером.
Ситуация 1: когда клиент делает синхронный вызов со значением параметра
{async=false}
по умолчанию. Есть два необязательных дополнительных параметра:on_push=function-name
иon_push_ctx=function-argument
. Когда клиент получает внеполосное сообщение в сессии, он вызывает «имя-функции(аргумент-функции)». Например, с такими значениями параметров:{on_push=table.insert, on_push_ctx=messages}
– клиент произведет вставку полученных данных в таблицу под названием „messages“.Ситуация 2: когда клиент делает асинхронный вызов с измененным значением параметра
{async=true}
. Здесь не разрешеныon_push
иon_push_ctx
, но сообщения можно увидеть путем вызоваpairs()
в цикле.Осложненная ситуация 2:
pairs()
зависит от времени ожидания. Таким образом, есть необязательный аргумент – время ожидания для итерации. Если время ожидания истечет до получения нового сообщения или окончательного ответа, вернется ошибка. Чтобы проверить наличие ошибки, можно использовать первый параметр в цикле (если цикл начинается с «for i, message in future:pairs()», то первым параметром в цикле будет i). Если это будетbox.NULL
, то второй параметр (в нашем примере «message») – это объект ошибки.Пример:
-- Создайте две оболочки. В оболочке №1 настройте сервер, а -- в нем функцию, которая содержит box.session.push: box.cfg{listen=3301} box.schema.user.grant('guest','read,write,execute','universe') x = 0 fiber = require('fiber') function server_function() x=x+1; fiber.sleep(1); box.session.push(x); end -- В оболочке №2 подключитесь к серверу в качестве клиента, который -- поддерживает Lua (как второй Tarantool-сервер, работающий -- в качестве клиента), и создайте таблицу, в которую мы будем получать сообщения: net_box = require('net.box') conn = net_box.connect(3301) messages_from_server = {} -- В оболочке №2 удаленно вызовите функцию и получите -- СИНХРОННОЕ внеполосное сообщение: conn:call('server_function', {}, {is_async = false, on_push = table.insert, on_push_ctx = messages_from_server}) messages_from_server -- Через секунду, во время которой происходит запрос fiber.sleep() -- в server_function, результат в таблице -- messages_from_server будет следующим: 1. Проверим: -- tarantool> messages_from_server -- --- -- - - 1 -- ... -- Хорошо. Это означает, что box.session.push(x) сработала, -- поскольку мы знаем, что x был 1. -- В оболочке №2 удаленно вызовите ту же самую функцию -- для получения АСИНХРОННОГО внеполосного сообщения. При этом мы не можем -- использовать параметры on_push и on_push_ctx, но можем использовать pairs(): future = conn:call('server_function', {}, {is_async = true}) messages = {} keys = {} for i, message in future:pairs() do table.insert(messages, message) table.insert(keys, i) end messages future:wait_result(1000) for i, message in future:pairs() do table.insert(messages, message) table.insert(keys, i) end messages -- Задержки нет, поскольку conn:call не ждет -- окончания вызова функции server_function. После первой итерации -- цикла pairs(), видим, что таблица пуста. Это выглядит так: -- tarantool> messages -- --- -- - - 2 -- - [] -- ... -- Это нормально, поскольку сервер еще не вызвал -- box.session.push(). При второй итерации -- цикла pairs(), видим значение x во время -- второго вызова box.session.push(). Так: -- tarantool> messages -- --- -- - - 2 -- - &0 [] -- - 2 -- - *0 -- ... -- Хорошо. Это означает, что сообщение было асинхронным, и -- box.session.push() выполнила свою задачу.
- message (