Модуль net.box
Модуль net.box
включает в себя коннекторы для удаленных систем с базами данных. Одним из вариантов, который рассматривается позднее, является подключение к MySQL, MariaDB или PostgreSQL (см. справочник по Модулям СУБД SQL). Другим вариантом, который рассматривается в данном разделе, является подключение к экземплярам Tarantool-сервера по сети.
Можно вызвать следующие методы:
require('net.box')
для получения объектаnet.box
(который называетсяnet_box
для примеров в данном разделе),net_box.connect()
для подключения и получения объекта подключения (который называетсяconn
для примеров в данном разделе),- другие процедуры
net.box()
, передающиеconn:
для выполнения запросов в удаленной системе базы данных, conn:close
для отключения.
Все методы net.box
безопасны для файберов, то есть можно безопасно обмениваться и использовать один и тот же объект подключения в нескольких файберах одновременно. Фактически так лучше всего работать в Tarantool’е. Когда несколько файберов используют одно соединение, все запросы передаются по одному сетевому сокету, но каждый файбер получает правильный ответ. Уменьшение количества активных сокетов снижает затрату ресурсов на системные вызовы и увеличивает общую производительность сервера. Однако, в некоторых случаях отдельного соединения недостаточно – например, когда необходимо отдавать приоритет разным запросам или использовать различные идентификаторы при аутентификации.
В большинстве методов net.box
можно использовать заключительный аргумент {options}
, который может быть:
{timeout=...}
. Например, метод с заключительным аргументом{timeout=1.5}
остановится через 1,5 секунды на локальном узле, хотя это не гарантирует, что выполнение остановится на удаленном сервере.{buffer=...}
. Например, см. модуль buffer.{is_async=...}
. Например, метод с заключительным аргументом{is_async=true}
не будет ждать результата выполнения запроса. См. описание is_async.{on_push=... on_push_ctx=...}
. Для получения внеполосных сообщений. См. описание box.session.push().
На диаграмме ниже представлены возможные состояния и варианты перехода из одного состояния в другое:
На этой диаграмме:
- Работа начинается с начального состояния „initial“.
- Выполнение метода
net_box.connect()
переводит состояние в „connecting“, создается рабочий файбер. - Если требуются аутентификация и загрузка схемы, можно позднее повторно войти в состояние загрузки схемы „fetch_schema“ из активного „active“, если запрос не будет выполнен из-за ошибки несовпадения версий схемы, то есть будет вызвана перезагрузка схемы.
- Метод
conn.close()
изменяет состояние на закрытое „closed“ и отключает рабочий процесс. Если транспорт уже находится в состоянии ошибки „error“,close()
не делает ничего.
Ниже приведен перечень всех функций модуля net.box
.
Имя | Назначение |
---|---|
net_box.connect() net_box.new() net_box.self |
Создание подключения |
conn:ping() | Выполнение команды проверки состояния PING |
conn:wait_connected() | Ожидание активности или закрытия подключения |
conn:is_connected() | Проверка активности или закрытия подключения |
conn:wait_state() | Ожидание нужного состояния |
conn:close() | Закрытие подключения |
conn.space.space-name:select{field-value} | Выбор одного или нескольких кортежей |
conn.space.space-name:get{field-value} | Выбор кортежа |
conn.space.space-name:insert{field-value} | Вставка кортежа |
conn.space.space-name:replace{field-value} | Вставка или замена кортежа |
conn.space.space-name:update{field-value} | Обновление кортежа |
conn.space.space-name:upsert{field-value} | Обновление кортежа |
conn.space.space-name:delete{field-value} | Удаление кортежа |
conn:eval() | Оценка и выполнение выражения в строке |
conn:call() | Вызов хранимой процедуры |
conn:timeout() | Установка времени ожидания |
conn:on_connect() | Определение триггера на подключение |
conn:on_disconnect() | Определение триггера на отключение |
conn:on_schema_reload() | Определение триггера при изменении схемы |
-
net_box.
new
(URI[, {option[s]}]) Примечание
Имена
connect()
иnew()
являются синонимами: предпочтительным будетconnect()
, аnew()
обеспечивает поддержку обратной совместимости.Создание нового подключения. Подключение устанавливается по требованию во время первого запроса. Можно повторно установить подключение автоматически после отключения (см. ниже опцию
reconnect_after
). Возвращается объектconn
, который поддерживает методы создание удаленных запросов, таких как select, update или delete.Возможные опции:
user/password
: есть два способа подключения к удаленному хосту: с использованием URI или параметровuser
(пользователь) иpassword
(пароль). Например, вместоconnect('username:userpassword@localhost:33301')
можно ввестиconnect('localhost:33301', {user = 'имя-пользователя', password='пароль-пользователя'})
.wait_connected
: по умолчанию, создание подключения блокируется до тех пор, пока подключение не будет установлено, но передачаwait_connected=false
заставит метод сразу же вернуться. Передача времени ожидания заставит метод ждать до возвращения (например,wait_connected=1.5
заставит ожидать подключения максимум 1,5 секунды).Примечание
Если присутствует
reconnect_after
,wait_connected
проигнорирует неустойчивые отказы. Ожидание заканчивается, когда подключение установлено или явным образом закрыто.reconnect_after
:net.box
автоматически подключается повторно в случае разрыва соединения или провала попытки подключения. В таком случае неустойчивые сетевые отказы становятся очевидными. Повторное подключение выполняется автоматически в фоновом режиме, поэтому запросы/обращения, не выполненные по причине потери соединения, явным образом выполняются повторно. Количество повторов не ограничено, попытки подключения выполняются в течение указанного времени ожидания (например,reconnect_after=5
– 5 секунд). После явного закрытия подключения или удаления сборщиком мусора в Lua попытки соединения повторно не выполняются. Значение по умолчанию для параметраreconnect_after
, как и для другихconnect
опций, равноnil
.call_16
: [с 1.7.2] по умолчанию, подключенияnet.box
соответствуют команде CALL нового бинарного протокола, который не поддерживает обратную совместимость с предыдущими версиями. Команда нового бинарного протокола для вызова CALL больше не ограничивает функцию в возврате массива кортежей и позволяет возвращать произвольный результат в формате MsgPack/JSON, включая scalar (скалярные значения), nil (нулевые значения) и void (пусто). Старый метод CALL оставлен нетронутым для обратной совместимости. В следующей основной версии он будет удален. Все драйверы для языков программирования будут постепенно переведены на использование нового метода CALL. Для подключения к экземпляру Tarantool’а, в котором используется старый метод CALL, укажитеcall_16=true
.console
: в зависимости от значения параметра поддерживаются различные методы (как если бы возвращались экземпляры разных классов). Еслиconsole = true
, можно использовать методыconn
:close()
,is_connected()
,wait_state()
,eval()
(в этом случае поддерживаются и бинарный сетевой протокол, и протокол Lua-консоли). Еслиconsole = false
(по умолчанию), также можно использовать методыconn
для работы с базой данных (в этом случае поддерживается только бинарный протокол). Устарел:console = true
объявлен устаревшим, вместо него следует использовать console.connect().connect_timeout
: количество секунд ожидания до возврата ошибки «error: Connection timed out».
Параметры: возвращает: объект подключения
тип возвращаемого значения: пользовательские данные
Примеры:
conn = net_box.connect('localhost:3301') conn = net_box.connect('127.0.0.1:3302', {wait_connected = false}) conn = net_box.connect('127.0.0.1:3303', {reconnect_after = 5, call_16 = true})
-
object
self
Для локального Tarantool-сервера есть заданный объект всегда установленного подключения под названием
net_box.self
. Он создан с целью облегчить полиморфное использование API модуляnet_box
. Таким образом,conn = net_box.connect('localhost:3301')
можно заменить наconn = net_box.self
.Однако, есть важно отличие встроенного подключения от удаленного:
- При встроенном подключении запросы без изменения данных не передают управление. При использовании удаленного подключения любой запрос может передавать управление исходя из правил неявной передачи управления, и состояние базы данных может измениться к тому времени, как управление вернется.
- Не учитывается ни один параметр, передаваемый в запросе (
is_async
,on_push
,timeout
).
-
object
conn
-
conn:
ping
([options]) Выполнение команды проверки состояния PING.
Параметры: - options (table) – поддерживается опция
timeout=секунды
возвращает: true (правда), если выполнено, false (ложь) в случае ошибки
тип возвращаемого значения: boolean (логический)
Пример:
net_box.self:ping({timeout = 0.5})
- options (table) – поддерживается опция
-
conn:
wait_connected
([timeout]) Ожидание активности или закрытия подключения.
Параметры: - timeout (number) – в секундах
возвращает: true (правда) при подключении, false (ложь), если не выполнено.
тип возвращаемого значения: boolean (логический)
Пример:
net_box.self:wait_connected()
-
conn:
is_connected
() Проверка активности или закрытия подключения.
возвращает: true (правда) при подключении, false (ложь), если не выполнено. тип возвращаемого значения: boolean (логический) Пример:
net_box.self:is_connected()
-
conn:
wait_state
(state[s][, timeout]) [с 1.7.2] Ожидание нужного состояния.
Параметры: - states (string) – необходимое состояние
- timeout (number) – в секундах
возвращает: true (правда) при подключении, false (ложь) при окончании времени ожидания или закрытии подключения
тип возвращаемого значения: boolean (логический)
Примеры:
-- бесконечное ожидание состояния 'active': conn:wait_state('active') -- ожидание в течение максимум 1,5 секунд: conn:wait_state('active', 1.5) -- бесконечное ожидание состояния `active` или `fetch_schema`: conn:wait_state({active=true, fetch_schema=true})
-
conn:
close
() Закрытие подключения.
Объекты подключения удаляются сборщиком мусора в Lua, как и любой другой Lua-объект, поэтому удалять их явным образом необязательно. Однако, поскольку close() представляет собой системный вызов, лучше всего закрыть соединение явным образом, когда оно больше не используется, с целью ускорения работы сборщика мусора.
Пример:
conn:close()
-
conn.space.<space-name>:select({field-value, ...} [, {options}])
conn.space.имя-спейса:select
({...})
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:select
{...}
(детали).Пример:
conn.space.testspace:select({1,'B'}, {timeout=1})
Примечание
Исходя из правил неявной передачи управления, локальный запрос
box.space.имя-спейса:select
{...}
не передает управление, а удаленныйconn.space.имя-спейса:select
{...}
передаст, поэтому глобальные переменные или кортежи в базе данных могут измениться во время удаленногоconn.space.имя-спейса:select
{...}
.
-
conn.space.<space-name>:get({field-value, ...} [, {options}])
conn.space.имя-спейса:get(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:get(...)
(детали).Пример:
conn.space.testspace:get({1})
-
conn.space.<space-name>:insert({field-value, ...} [, {options}])
conn.space.имя-спейса:insert(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:insert(...)
(детали).Пример:
conn.space.testspace:insert({2,3,4,5}, {timeout=1.1})
-
conn.space.<space-name>:replace({field-value, ...} [, {options}])
conn.space.имя-спейса:replace(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:replace(...)
(детали).Пример:
conn.space.testspace:replace({5,6,7,8})
-
conn.space.<space-name>:update({field-value, ...} [, {options}])
conn.space.имя-спейса:update(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:update(...)
(детали).Пример:
conn.space.Q:update({1},{{'=',2,5}}, {timeout=0})
-
conn.space.<space-name>:upsert({field-value, ...} [, {options}])
conn.space.имя-спейса:upsert(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:upsert(...)
(детали).
-
conn.space.<space-name>:delete({field-value, ...} [, {options}])
conn.space.имя-спейса:delete(...)
– это удаленный вызов, аналогичный локальному вызовуbox.space.имя-спейса:delete(...)
(детали).
-
conn:
eval
(Lua-string[, {arguments}[, {options}]]) conn:eval(Lua-строка)
оценивает и выполняет выражение в Lua-строке, которое может представлять собой любое выражение или несколько выражений. Требуются права на выполнение; если у пользователя таких прав нет, администратор может их выдать с помощьюbox.schema.user.grant(имя-пользователя, 'execute', 'universe')
.Чтобы гарантировать, что
conn:eval
вернет то, что возвращает выражение на Lua, начните Lua-строку со слова «return» (вернуть).Примеры:
tarantool> --Lua-строка tarantool> conn:eval('function f5() return 5+5 end; return f5();') --- - 10 ... tarantool> --Lua-строка, {аргументы} tarantool> conn:eval('return ...', {1,2,{3,'x'}}) --- - 1 - 2 - [3, 'x'] ... tarantool> --Lua-строка, {аргументы}, {парметры} tarantool> conn:eval('return {nil,5}', {}, {timeout=0.1}) --- - [null, 5] ...
-
conn:
call
(function-name[, {arguments}[, {options}]]) conn:call('func', {'1', '2', '3'})
– это удаленный вызов, аналогичныйfunc('1', '2', '3')
. Таким образом,conn:call
представляет собой удаленный вызов хранимой процедуры.conn:call
возвращает то, что возвращает функция.Ограничение: вызванная функция не может вернуть функцию, например, если
func2
определяется какfunction func2 () return func end
, тоconn:call(func2)
вернет ошибку «error: unsupported Lua type „function“».Примеры:
tarantool> -- создание 2 функций с conn:eval() tarantool> conn:eval('function f1() return 5+5 end;') tarantool> conn:eval('function f2(x,y) return x,y end;') tarantool> -- вызов первой функции без параметров и опций tarantool> conn:call('f1') --- - 10 ... tarantool> -- вызов второй функции с двумя параметрами и одной опцией tarantool> conn:call('f2',{1,'B'},{timeout=99}) --- - 1 - B ...
-
conn:
timeout
(timeout) timeout(...)
– это надстройка, которая определяет время ожидания для запроса. С версии 1.7.4 этот метод объявлен устаревшим – лучше передать значение времени ожидания с помощью параметра{options}
.Пример:
conn:timeout(0.5).space.tester:update({1}, {{'=', 2, 15}})
Хотя
timeout(...)
объявлен устаревшим, все удаленные вызовы поддерживают его. Использование надстройки обеспечивает совместимость API удаленного соединения с локальным, поэтому отпадает необходимость в отдельном аргументеtimeout
, который проигнорирует локальная версия. После отправки запроса его нельзя отменить с удаленного сервера даже по истечении времени задержки: окончание времени задержки прерывает только ожидание ответа от удаленного сервера, а не сам запрос.
-
conn:
request
(... {is_async=...}) {is_async=true|false}
– это опция, которую можно применить во всех запросахnet_box
, включаяconn:call
,conn:eval
и запросыconn.space.space-name
.По умолчанию,
is_async=false
, что означает, что запросы будут синхронными для файбера. Файбер блокируется в ожидании ответа на запрос или до истечения времени ожидания. До версии Tarantool’а 1.10 единственным способом выполнения асинхронных запросов было использование отдельных файберов.is_async=true
означает, что запросы будут асинхронными для файбера. Запрос вызывает передачу управления, но файбер не входит в режим ожидания. Сразу же возвращается результат, но это будет не результат запроса, а объект, который может использовать вызывающая программа для получения результат запроса.У такого сразу же возвращаемого объекта, который мы называем «future» (будущий), есть собственные методы:
future:is_ready()
вернет true (правда), если доступен результат запроса,future:result()
используется для получения результата запроса (возвращает ответ на запрос или nil в случае, если ответ еще не готов или произошла какая-либо ошибка),future:wait_result(timeout)
будет ждать, когда результат запроса будет доступен, а затем получит его или выдаст ошибку, если по истечении времени ожидания результат не получен.future:discard()
откажется от объекта.
В обычной ситуации пользователь введет команду
future=имя-запроса(...{is_async=true})
, а затем либо цикл с проверкойfuture:is_ready()
до тех пор, пока он не вернет true, и получением результата с помощьюrequest_result=future:result()
, либо же командуrequest_result=future:wait_result(...)
. Возможен вариант, когда клиент проверяет наличие внеполосных сообщений от сервера, вызывая в циклеpairs()
– см. box.session.push().Можно использовать
future:discard()
, чтобы соединение забыло об ответе – если получен ответ для отброшенного объекта, то он будет проигнорирован, так что размер таблицы запросов будет уменьшен, а другие запросы будут выполняться быстрее.Пример:
tarantool> future = conn.space.tester:insert({900},{is_async=true}) --- ... tarantool> future --- - method: insert response: [900] cond: cond on_push_ctx: [] on_push: 'function: builtin#91' ... tarantool> future:is_ready() --- - true ... tarantool> future:result() --- - [900] ...
Как правило,
{is_async=true}
используется только при большой загрузке (более 100 000 запросов в секунду) и большой задержке чтения (более 1 секунды), или же при необходимости отправки нескольких одновременных запросов, которые собирают ответы (что иногда называется «отображение-свертка»).Примечание
Хотя окончательный результат асинхронного запроса не отличается от результата синхронного запроса, у него другая структура: таблица, а не неупакованные значения.
-
В модуле net.box
можно использовать следующие триггеры:
-
conn:
on_connect
([trigger-function[, old-trigger-function]]) Определение триггера, исполняемого, когда устанавливается новое соединение (и при условии, что аутентификация и сборка схемы завершены) при таком событии, как
net_box.connect
. Если триггер не срабатывает и выкидывает исключение, статус подключения меняется на „error“.В таком случае соединение прерывается, независимо от значения опцииreconnect_after
. Может вызываться столько раз, сколько раз происходит переподключение, если значение параметраreconnect_after
больше нуля.Параметры: - trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
conn
- old-trigger-function (function) – существующая функция с триггером, которую заменит новая
возвращает: nil или указатель функции
- trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
-
conn:
on_disconnect
([trigger-function[, old-trigger-function]]) Определение триггера, исполняемого после закрытия соединения. Если функция с триггером вызывает ошибку, то ошибка записывается в журнал, в противном случае записей не будет. Выполнение прекращается после явного закрытия соединения или удаления сборщиком мусора в Lua.
Параметры: - trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
conn
- old-trigger-function (function) – существующая функция с триггером, которую заменит новая
возвращает: nil или указатель функции
- trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
-
conn:
on_schema_reload
([trigger-function[, old-trigger-function]]) Определение триггера, исполняемого во время выполнения определенной операции на удаленном сервере после обновления схемы. Другими словами, если запрос к серверу не выполняется из-за ошибки несовпадения версии схемы, происходит перезагрузка схемы.
Параметры: - trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
conn
- old-trigger-function (function) – существующая функция с триггером, которую заменит новая
возвращает: nil или указатель функции
Примечание
Если указаны параметры
(nil, old-trigger-function)
, старый триггер будет удален.Если не указан ни один параметр, ответом будет список существующих функций с триггером.
Подробная информация о характеристиках триггера находится в разделе Триггеры.
- trigger-function (function) – функция, в которой будет триггер. В качестве первого аргумента берет объект
Ниже приводится пример использования большинства методов net.box
.
Данный пример сработает на конфигурации из песочницы, предполагается, что:
- экземпляр Tarantool’а запущен на
localhost 127.0.0.1:3301
, - создан спейс под названием
tester
с первичным числовым ключом и кортежем, в котором есть ключ со значением= 800, - у текущего пользователя есть права на чтение, запись и выполнение.
Ниже приведены команды для быстрой настройки песочницы:
box.cfg{listen = 3301}
s = box.schema.space.create('tester')
s:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})
t = s:insert({800, 'TEST'})
box.schema.user.grant('guest', 'read,write,execute', 'universe')
А здесь приведен пример:
tarantool> net_box = require('net.box')
---
...
tarantool> function example()
> local conn, wtuple
> if net_box.self:ping() then
> table.insert(ta, 'self:ping() succeeded')
> table.insert(ta, ' (no surprise -- self connection is pre-established)')
> end
> if box.cfg.listen == '3301' then
> table.insert(ta,'The local server listen address = 3301')
> else
> table.insert(ta, 'The local server listen address is not 3301')
> table.insert(ta, '( (maybe box.cfg{...listen="3301"...} was not stated)')
> table.insert(ta, '( (so connect will fail)')
> end
> conn = net_box.connect('127.0.0.1:3301')
> conn.space.tester:delete({800})
> table.insert(ta, 'conn delete done on tester.')
> conn.space.tester:insert({800, 'data'})
> table.insert(ta, 'conn insert done on tester, index 0')
> table.insert(ta, ' primary key value = 800.')
> wtuple = conn.space.tester:select({800})
> table.insert(ta, 'conn select done on tester, index 0')
> table.insert(ta, ' number of fields = ' .. #wtuple)
> conn.space.tester:delete({800})
> table.insert(ta, 'conn delete done on tester')
> conn.space.tester:replace({800, 'New data', 'Extra data'})
> table.insert(ta, 'conn:replace done on tester')
> conn.space.tester:update({800}, {{'=', 2, 'Fld#1'}})
> table.insert(ta, 'conn update done on tester')
> conn:close()
> table.insert(ta, 'conn close done')
> end
---
...
tarantool> ta = {}
---
...
tarantool> example()
---
...
tarantool> ta
---
- - self:ping() succeeded
- ' (no surprise -- self connection is pre-established)'
- The local server listen address = 3301
- conn delete done on tester.
- conn insert done on tester, index 0
- ' primary key value = 800.'
- conn select done on tester, index 0
- ' number of fields = 1'
- conn delete done on tester
- conn:replace done on tester
- conn update done on tester
- conn close done
...