{"id":306780,"date":"2020-07-10T21:01:13","date_gmt":"2020-07-10T21:01:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=306780"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=306780","title":{"rendered":"\u0421\u043e\u0437\u0434\u0430\u0435\u0308\u043c \u0441 \u043d\u0443\u043b\u044f \u0432\u044b\u0441\u043e\u043a\u043e\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Tarantool"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/510440\/\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/fs\/fk\/f8\/fsfkf8dh0poigt7znuwrcyanlja.jpeg\" alt=\"image\"><\/p>\n<p>  <\/p>\n<p>\u0412 2013 \u044f \u043f\u0440\u0438\u0448\u0435\u043b \u0432 Mail.ru Group, \u0438 \u044f \u0440\u0435\u0448\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439, \u043d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0423\u0441\u043b\u044b\u0448\u0430\u043b, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u2014 Tarantool. \u0423\u0437\u043d\u0430\u043b, \u043a\u0430\u043a \u043e\u043d \u0443\u0441\u0442\u0440\u043e\u0435\u043d, \u0438 \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0432 \u043d\u0435\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0431\u0440\u043e\u043a\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439. <\/p>\n<p>  <\/p>\n<p>\u042f \u043f\u043e\u0448\u0451\u043b \u043a \u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443 \u043f\u043e Tarantool \u2014 \u041a\u043e\u0441\u0442\u0435 \u041e\u0441\u0438\u043f\u043e\u0432\u0443 \u2014 \u0438 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 C, \u043a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 Tarantool, \u043d\u043e\u2026 \u041d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0434\u0435\u043d\u044c \u041a\u043e\u0441\u0442\u044f \u0434\u0430\u043b \u043c\u043d\u0435 <a href=\"https:\/\/github.com\/mailru\/tntlua\/commit\/f879dfb6981dc82287b7243074ca6cc9c6038369\">\u0441\u043a\u0440\u0438\u043f\u0442<\/a> \u043d\u0430 250 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b.<\/p>\n<p>  <\/p>\n<p>\u0421 \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u044f \u0432\u043b\u044e\u0431\u0438\u043b\u0441\u044f \u0432 Tarantool. \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u0443\u044e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0421\u0423\u0411\u0414 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0448\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, Tarantool \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0441\u044f, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043f\u043e\u0434 \u0432\u043b\u0438\u044f\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0434\u0435\u0438 \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0441\u044c. \u042f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c Tarantool, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438 2.2.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u0431\u044b\u043b \u0437\u043d\u0430\u043a\u043e\u043c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439, \u0438 \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 Beanstalkd. \u0423 \u043d\u0435\u0433\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044e (\u043e\u0431\u0440\u044b\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438. \u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435.<\/p>\n<p>  <\/p>\n<p>\u0421\u0430\u043c \u0441\u0435\u0440\u0432\u0438\u0441 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0438 \u0445\u0440\u0430\u043d\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0438; \u0435\u0441\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u044b: \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u043d\u043e\u0441\u044f\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 (\u043c\u0435\u0442\u043e\u0434 <code>put<\/code>); \u0438 \u043a\u043e\u043d\u0441\u044e\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0435\u0440\u0443\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0440\u0430\u0431\u043e\u0442\u0443 (\u043c\u0435\u0442\u043e\u0434 <code>take<\/code>).<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ls\/ih\/br\/lsihbrry8v22ehrzkh0xrxkrjas.png\"><\/div>\n<p>  <\/p>\n<p>\u0416\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043e\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0445\u0435\u043c\u043e\u0439. \u0417\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>put<\/code> \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 ready. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f <code>take<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 taken. \u0418\u0437 taken \u0437\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 (<code>ack<\/code>) \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0430, \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0430 \u0432 ready (<code>release<\/code>).<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/n7\/qz\/i7\/n7qzi7pusqjch-ypd0kkbirr044.png\"><\/div>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u044d\u0442\u0443 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u0432\u0432\u0435\u0441\u0442\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u0434\u0430\u0447:<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/oa\/8h\/om\/oa8hommfq00gxub7j9jui48twz8.png\"><\/div>\n<p>  <\/p>\n<h2 id=\"podgotovka-okruzheniya\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>Tarantool \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u2014 \u044d\u0442\u043e, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, LuaJIT-\u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440. \u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b init.lua, \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430, \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043c \u0432\u044b\u0437\u043e\u0432 <code>box.cfg()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0421\u0423\u0411\u0414. <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c. \u0417\u0430\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0435\u0433\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on()  box.cfg{}  require'console'.start() os.exit()<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u0430\u044f, \u0432 \u043d\u0435\u0439 \u0441\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c. \u041d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u043b\u0433\u043e \u0438 \u043c\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u043d\u0438\u0445. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u0442\u0435 10-15 \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0441\u0440\u0430\u0437\u0443 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c strict. \u042f\u0437\u044b\u043a Lua \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u0435\u043d \u0432 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0438 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0430\u043c \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u0445. \u041a\u0441\u0442\u0430\u0442\u0438, \u0435\u0441\u043b\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c Tarantool \u0441\u0430\u043c\u043e\u043c\u0443 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>DEBUG<\/code>, \u0442\u043e <code>strict<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>tarantool<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool init.lua<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">2020-07-09 20:00:11.344 [30043] main\/102\/init.lua C&gt; Tarantool 2.2.3-1-g98ecc909a 2020-07-09 20:00:11.345 [30043] main\/102\/init.lua C&gt; log level 5 2020-07-09 20:00:11.346 [30043] main\/102\/init.lua I&gt; mapping 268435456 bytes for memtx tuple arena... 2020-07-09 20:00:11.347 [30043] main\/102\/init.lua I&gt; mapping 134217728 bytes for vinyl tuple arena... 2020-07-09 20:00:11.370 [30043] main\/102\/init.lua I&gt; instance uuid 38c59892-263e-42de-875c-8f67539191a3 2020-07-09 20:00:11.371 [30043] main\/102\/init.lua I&gt; initializing an empty data directory 2020-07-09 20:00:11.408 [30043] main\/102\/init.lua I&gt; assigned id 1 to replica 38c59892-263e-42de-875c-8f67539191a3 2020-07-09 20:00:11.408 [30043] main\/102\/init.lua I&gt; cluster uuid 7723bdf4-24e8-4957-bd6c-6ab502a1911c 2020-07-09 20:00:11.425 [30043] snapshot\/101\/main I&gt; saving snapshot `.\/00000000000000000000.snap.inprogress' 2020-07-09 20:00:11.437 [30043] snapshot\/101\/main I&gt; done 2020-07-09 20:00:11.439 [30043] main\/102\/init.lua I&gt; ready to accept requests 2020-07-09 20:00:11.439 [30043] main\/104\/checkpoint_daemon I&gt; scheduled next checkpoint for Thu Jul  9 21:11:59 2020 tarantool&gt; <\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"pishem-ochered\">\u041f\u0438\u0448\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/h3>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>queue.lua<\/code> \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0451 \u043f\u0440\u044f\u043c\u043e \u0432 <code>init.lua<\/code>, \u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c <code>queue<\/code> \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 <code>init.lua<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on()  box.cfg{}  queue = require 'queue'  require'console'.start() os.exit()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0432 <code>queue.lua<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0433\u0434\u0435-\u0442\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u0434\u0430\u0447\u0430\u0445. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043f\u0435\u0439\u0441 (space) \u2014 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0431\u0435\u0437 \u043e\u043f\u0446\u0438\u0439, \u043d\u043e \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043a\u043e\u0435-\u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c. \u0427\u0442\u043e\u0431\u044b \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f, \u043c\u044b \u0443\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e \u0441\u043f\u0435\u0439\u0441 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 (<code>if_not_exists<\/code>). \u0422\u0430\u043a\u0436\u0435 \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c Tarantool \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u043e\u043b\u0435\u0439 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (\u043b\u0443\u0447\u0448\u0435 \u0442\u0430\u043a \u0438 \u0434\u0435\u043b\u0430\u0442\u044c). \u0422\u0430\u043a \u043c\u044b \u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443. \u041c\u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e <code>id<\/code> \u0437\u0430\u0434\u0430\u0447, \u0438\u0445 \u0441\u0442\u0430\u0442\u0443\u0441\u044b \u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041c\u043d\u0435 \u043d\u0435 \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0436\u0430\u0442\u044c. \u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0431\u0435\u0437 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e <code>id<\/code>. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0439\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0442\u0438\u043f \u043f\u043e\u043b\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b \u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0438 \u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.schema.create_space('queue',{ if_not_exists = true; })  box.space.queue:format( {     { name = 'id';     type = 'number' },     { name = 'status'; type = 'string' },     { name = 'data';   type = '*'      }, } );  box.space.queue:create_index('primary', {    parts = { 1,'number' };    if_not_exists = true; })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>queue<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0441\u0442\u0438 \u0432 \u0441\u0435\u0431\u0435 \u043d\u0430\u0448\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438 \u043c\u0435\u0442\u043e\u0434\u044b. \u0418 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 (<code>put<\/code>) \u0438 \u0432\u0437\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 (<code>take<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0423 \u0437\u0430\u0434\u0430\u0447 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u0414\u043b\u044f \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u043b\u0430 \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u043e \u044f \u043b\u044e\u0431\u043b\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0431\u0443\u043a\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u043c\u0438 \u0438 \u043e\u043d\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043c\u0435\u0441\u0442\u0430 \u043f\u0440\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0434\u0432\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0430: <code>R=READY<\/code> \u0438 <code>T=TAKEN<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local queue = {}  local STATUS = {} STATUS.READY = 'R' STATUS.TAKEN = 'T'  function queue.put(...)  end  function queue.take(...)  end  return queue<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c <code>put<\/code>? \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>id<\/code> \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043f\u0435\u0439\u0441 \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c <code>READY<\/code>. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430, \u043c\u044b \u0432\u043e\u0437\u044c\u043c\u0451\u043c <code>clock.realtime<\/code>. \u0414\u043b\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043e\u043d \u0445\u043e\u0440\u043e\u0448 \u0442\u0435\u043c, \u0447\u0442\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (\u043d\u043e \u0443\u0447\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u0447\u0430\u0441\u044b \u043c\u043e\u0433\u0443\u0442 \u0436\u0451\u0441\u0442\u043a\u043e \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f, \u0438 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430\u0434\u0430\u0447 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0440\u0443\u0448\u0435\u043d). \u0422\u0430\u043a\u0436\u0435, \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f, \u043a\u043e\u0433\u0434\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0435\u0442 \u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0442\u0430\u043a\u0438\u043c <code>id<\/code>, \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0438\u0446\u0443. \u041d\u0430 \u044d\u0442\u043e \u0443\u0439\u0434\u0443\u0442 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0438 \u044d\u0442\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u043c\u0430\u043b\u043e\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u043f\u043e\u0441\u0442\u0440\u0430\u0434\u0430\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0447\u0438\u043d\u043a\u0438 \u0432 \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local clock = require 'clock' function gen_id()     local new_id     repeat         new_id = clock.realtime64()     until not box.space.queue:get(new_id)     return new_id end  function queue.put(...)     local id = gen_id()     return box.space.queue:insert{ id, STATUS.READY, { ... } } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>put<\/code>, \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Tarantool \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043e\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u0442\u0430\u043f\u043b (\u043a\u043e\u0440\u0442\u0435\u0436). \u0412 \u043d\u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043a\u043b\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0434\u0430\u0436\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0422\u0430\u043f\u043b\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 Tarantool \u0445\u0440\u0430\u043d\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 MessagePack, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">tarantool&gt; queue.put(&quot;hello&quot;) --- - [1594325382148311477, 'R', ['hello']] ...  tarantool&gt; queue.put(&quot;my&quot;,&quot;data&quot;,1,2,3) --- - [1594325394527830491, 'R', ['my', 'data', 1, 2, 3]] ...  tarantool&gt; queue.put({ complex = { struct = &quot;data&quot; }}) --- - [1594325413166109943, 'R', [{'complex': {'struct': 'data'}}]] ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u043c\u044b \u043a\u043b\u0430\u0434\u0451\u043c, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043f\u0435\u0439\u0441\u0435. \u041c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u043f\u0435\u0439\u0441\u0430 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043c \u043b\u0435\u0436\u0438\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; box.space.queue:select() --- - - [1594325382148311477, 'R', ['hello']]   - [1594325394527830491, 'R', ['my', 'data', 1, 2, 3]]   - [1594325413166109943, 'R', [{'complex': {'struct': 'data'}}]] ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0431\u0440\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>take<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c. \u041c\u044b \u0431\u0435\u0440\u0435\u043c \u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 <code>READY<\/code>. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u043c\u0443 \u043a\u043b\u044e\u0447\u0443 \u0438 \u043d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0432\u0443\u044e \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u043d\u043e \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u044d\u0442\u043e\u0442 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0451\u0442. \u041d\u0443\u0436\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e \u043f\u043e\u043b\u044e \u0441\u0442\u0430\u0442\u0443\u0441\u0430. \u041e\u0434\u043d\u0430 \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0447\u0435\u0440\u0442 Tarantool, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442 \u0435\u0433\u043e \u043e\u0442 key-value \u0431\u0430\u0437, \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b, \u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u043a \u0432 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0431\u0430\u0437\u0430\u0445: \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u043b\u044f, \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043d\u044b\u0435, \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u043d\u0434\u0435\u043a\u0441, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0436\u0435\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u2014 \u044d\u0442\u043e \u0441\u0442\u0430\u0442\u0443\u0441. \u041f\u043e \u043d\u0435\u043c\u0443 \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c. \u0410 \u0432\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043b\u0435 \u2014 \u044d\u0442\u043e <code>id<\/code>. \u041e\u043d \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0442 \u043f\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u044e \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u0430. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space.queue:create_index('status', {     parts = { 2, 'string', 1, 'number' };     if_not_exists = true; })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0451\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438. \u0415\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a \u0441\u043f\u0435\u0439\u0441\u0443 \u043a\u0430\u043a <code>pairs<\/code>. \u0412 \u043d\u0435\u0433\u043e \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0430. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u0435\u0439: \u0438\u0449\u0435\u043c \u043f\u043e \u043f\u0435\u0440\u0432\u043e\u043c\u0443, \u0430 \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u043e \u0432\u0442\u043e\u0440\u043e\u043c\u0443. \u0413\u043e\u0432\u043e\u0440\u0438\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\u043c \u0442\u0430\u043f\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0440\u0430\u0432\u043d\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0430\u0442\u0443\u0441\u0443 <code>READY<\/code>. \u0418 \u0431\u0443\u0434\u0435\u043c \u0438\u0445 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0436\u0435 \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u0430. \u0415\u0441\u043b\u0438 \u043c\u044b \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u0448\u043b\u0438, \u0442\u043e \u0431\u0435\u0440\u0451\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c. \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0438\u043a\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439, \u043a\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442 \u0441 \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>take<\/code>, \u043d\u0435 \u0432\u0437\u044f\u043b \u0435\u0451. \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447 \u043d\u0435\u0442, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.take()     local found = box.space.queue.index.status         :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)     if found then         return box.space.queue             :update( {found.id}, {{'=', 2, STATUS.TAKEN }})     end     return end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0430\u043f\u043b\u0430 \u0432 Tarantool \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u041e\u043d \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043c\u0435\u043d, \u043e\u043d \u043d\u0443\u043c\u0435\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0442\u0430\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445, \u043a\u0430\u043a <code>update<\/code>, \u0434\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u043b\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0438\u043c\u044f \u043f\u043e\u043b\u044f \u0438 \u043d\u043e\u043c\u0435\u0440. \u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u043d\u0430\u043c\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local F = {} for no,def in pairs(box.space.queue:format()) do     F[no] = def.name     F[def.name] = no end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space.queue:format( {     { name = 'id';     type = 'number' },     { name = 'status'; type = 'string' },     { name = 'data';   type = '*'      }, } );  local F = {} for no,def in pairs(box.space.queue:format()) do     F[no] = def.name     F[def.name] = no end  box.space.queue:create_index('primary', {    parts = { F.id, 'number' };    if_not_exists = true; })  box.space.queue:create_index('status', {     parts = { F.status, 'string', F.id, 'number' };     if_not_exists = true; })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>take<\/code> \u0446\u0435\u043b\u0438\u043a\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.take(...)     for _,t in         box.space.queue.index.status         :pairs({ STATUS.READY },{ iterator='EQ' })     do         return box.space.queue:update({t.id},{             { '=', F.status, STATUS.TAKEN }         })     end     return end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041f\u043e\u043b\u043e\u0436\u0438\u043c \u043e\u0434\u043d\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u043c <code>take<\/code> \u0434\u0432\u0430\u0436\u0434\u044b. \u0415\u0441\u043b\u0438 \u043a \u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u043f\u0435\u0439\u0441\u0435, \u043c\u043e\u0436\u0435\u043c \u0435\u0433\u043e \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>box.space.queue:truncate()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; queue.put(&quot;my&quot;,&quot;data&quot;,1,2,3) --- - [1594325927025602515, 'R', ['my', 'data', 1, 2, 3]] ...  tarantool&gt; queue.take() --- - [1594325927025602515, 'T', ['my', 'data', 1, 2, 3]] ...  tarantool&gt; queue.take() --- ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 <code>take<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u043c \u0442\u0443 \u0441\u0430\u043c\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438. \u0410 \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u043e\u0432\u0435\u043c <code>take<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e ready-\u0437\u0430\u0434\u0430\u0447 (\u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 <code>R<\/code>) \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442. \u041c\u043e\u0436\u0435\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e\u043c, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 <code>select<\/code> \u0438\u0437 \u0441\u043f\u0435\u0439\u0441\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; box.space.queue:select() --- - - [1594325927025602515, 'T', ['my', 'data', 1, 2, 3]] ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0435\u0440\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443, \u0434\u043e\u043b\u0436\u0435\u043d \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0435\u0451 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u043b\u0438\u0431\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0435\u0441\u043b\u0438 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u0422\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0430\u0447\u0443 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u043a\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: <code>ack<\/code> \u0438 <code>release<\/code>. \u041e\u043d\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 <code>id<\/code> \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0438\u0449\u0443\u0442 \u0435\u0451. \u0415\u0441\u043b\u0438 \u0443 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u0432\u0437\u044f\u0442\u043e\u0439, \u0442\u043e \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0435\u0451. \u042d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436\u0438. \u041e\u0434\u043d\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0434\u0440\u0443\u0433\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 <code>ready<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.ack(id)     local t = assert(box.space.queue:get{id},&quot;Task not exists&quot;)     if t and t.status == STATUS.TAKEN then         return box.space.queue:delete{t.id}     else         error(&quot;Task not taken&quot;)     end end  function queue.release(id)     local t = assert(box.space.queue:get{id},&quot;Task not exists&quot;)     if t and t.status == STATUS.TAKEN then         return box.space.queue:update({t.id},{{'=', F.status, STATUS.READY }})     else         error(&quot;Task not taken&quot;)     end end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438. \u041a\u043b\u0430\u0434\u0451\u043c \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0431\u0435\u0440\u0451\u043c \u043f\u0435\u0440\u0432\u0443\u044e, \u0437\u0430\u0442\u0435\u043c \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u043c \u0435\u0451. \u041e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 <code>R<\/code>. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u0437\u043e\u0432 <code>take<\/code> \u0431\u0435\u0440\u0451\u0442 \u0442\u0443 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0443. \u0415\u0441\u043b\u0438 \u043c\u044b \u0435\u0451 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, \u043e\u043d\u0430 \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f. \u0422\u0440\u0435\u0442\u0438\u0439 \u0432\u044b\u0437\u043e\u0432 <code>take<\/code> \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u0443\u0436\u0435 \u0432\u0442\u043e\u0440\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u0437\u044f\u0442\u0430, \u0442\u043e \u043e\u043d\u0430 \u043d\u0435 \u0432\u044b\u0434\u0430\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u043a\u043e\u043c\u0443-\u043d\u0438\u0431\u0443\u0434\u044c. <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; queue.put(&quot;task 1&quot;) --- - [1594326185712343931, 'R', ['task 1']] ...  tarantool&gt; queue.put(&quot;task 2&quot;) --- - [1594326187061434882, 'R', ['task 2']] ...  tarantool&gt; task = queue.take() return task --- - [1594326185712343931, 'T', ['task 1']] ...  tarantool&gt; queue.release(task.id) --- - [1594326185712343931, 'R', ['task 1']] ...  tarantool&gt; task = queue.take() return task --- - [1594326185712343931, 'T', ['task 1']] ...  tarantool&gt; queue.ack(task.id) --- - [1594326185712343931, 'T', ['task 1']] ...  tarantool&gt; task = queue.take() return task --- - [1594326187061434882, 'T', ['task 2']] ...  tarantool&gt; queue.ack(task.id) --- - [1594326187061434882, 'T', ['task 2']] ...  tarantool&gt; task = queue.take() return task --- - null ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0430\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u041c\u044b \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u043e \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>take<\/code>, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043b\u0438\u0431\u043e \u0437\u0430\u0434\u0430\u0447\u0443, \u043b\u0438\u0431\u043e \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. \u0415\u0441\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u0434\u0430\u0447 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e, \u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u043d \u0431\u0443\u0434\u0435\u0442, \u043d\u043e \u0432\u0445\u043e\u043b\u043e\u0441\u0442\u0443\u044e, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u044f, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f CPU. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">while true do     local task = queue.take()     if task then         -- ...     end end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u00ab\u043a\u0430\u043d\u0430\u043b\u00bb (\u0438\u043b\u0438 <code>channel<\/code>). \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u041f\u043e \u0441\u0443\u0442\u0438, \u044d\u0442\u043e FIFO-\u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0444\u0430\u0439\u0431\u0435\u0440\u0430\u043c\u0438. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u0431\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0430\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043c \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0441\u0435\u0442\u0438 \u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043d\u0435\u0439 \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u0412 \u0444\u0430\u0439\u0431\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0448 Lua-\u043a\u043e\u0434, \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0444\u0430\u0439\u0431\u0435\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0436\u0434\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0438, \u0447\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043d\u043e\u0432\u0430\u044f. <\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043d\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a: \u0432 \u043d\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u0443\u0444\u0435\u0440 \u043d\u0430 N \u0441\u043b\u043e\u0442\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0437 \u043a\u0430\u043d\u0430\u043b\u0430. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b \u0431\u0435\u0437 \u0431\u0443\u0444\u0435\u0440\u043d\u043e\u0439 \u0451\u043c\u043a\u043e\u0441\u0442\u0438, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0435 \u0441\u043b\u043e\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0442\u043e-\u0442\u043e \u0436\u0434\u0435\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u0430\u043d\u0430\u043b \u043d\u0430 \u0434\u0432\u0430 \u0431\u0443\u0444\u0435\u0440\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0412 \u043d\u0435\u043c \u0434\u0432\u0430 \u0441\u043b\u043e\u0442\u0430 \u043f\u043e\u0434 <code>put<\/code>. \u0415\u0441\u043b\u0438 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c, \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0442\u0440\u0435\u0442\u0438\u0439 \u0441\u043b\u043e\u0442 \u043f\u043e\u0434 <code>put<\/code>. \u0415\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0430\u043b, \u0442\u043e \u0442\u0440\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 <code>put<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u0441\u044f \u0431\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438, \u0430 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 <code>put<\/code> \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c \u0442\u043e\u0442 \u0444\u0430\u0439\u0431\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043b\u0430\u0434\u0435\u0442 \u0432 \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0430\u043b. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0444\u0430\u0439\u0431\u0435\u0440\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435. \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u0432\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u043a\u0430\u043d\u0430\u043b\u0430\u043c\u0438 \u0432 Go, \u0442\u043e \u0442\u0430\u043c \u043e\u043d\u0438 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435:<\/p>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/jl\/1j\/i0\/jl1ji0iw4bf4lbonwdotytbgrig.png\"><\/div>\n<p>  <\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>take<\/code>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442: \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u0436\u0434\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0446\u0438\u043a\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0451\u0442, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0436\u0434\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u0430\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c. \u0415\u043b\u0438 \u0444\u0430\u0439\u0431\u0435\u0440 \u00ab\u0441\u043f\u0438\u0442\u00bb \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435, \u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u0442\u044c \u0438\u0437\u0432\u043d\u0435, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0430\u043b.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local fiber = require 'fiber' queue._wait = fiber.channel() function queue.take(timeout)     if not timeout then timeout = 0 end     local now = fiber.time()     local found     while not found do         found = box.space.queue.index.status             :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)         if not found then             local left = (now + timeout) - fiber.time()             if left &lt;= 0 then return end             queue._wait:get(left)         end     end     return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }}) end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0442\u043e\u0433\u043e: <code>take<\/code> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u0437\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0451. \u041d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043e\u0436\u0434\u0430\u0442\u044c \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0442\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430. \u041f\u0440\u0438\u0447\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u0431\u0435\u0440 \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0434\u043e\u0431\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b, \u043c\u043e\u0436\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 <code>init.lua<\/code> \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>fiber<\/code> \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">fiber = require 'fiber'<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u0431\u0435\u0440\u0430. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0444\u0430\u0439\u0431\u0435\u0440\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u0447\u0435\u0440\u0435\u0437 0,1 \u0441. \u0422\u043e \u0435\u0441\u0442\u044c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u0441\u0442\u0430\u044f, \u0430 \u0447\u0435\u0440\u0435\u0437 0,1 \u0441. \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0437\u043e\u0432 <code>take<\/code> \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c 3. \u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 <code>take<\/code> \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0437\u0430\u0434\u0430\u0447\u0443. \u041d\u0435 \u043d\u0430\u0439\u0434\u044f \u0435\u0451, \u043e\u043d \u0443\u0441\u043d\u0451\u0442 \u043d\u0430 3 \u0441. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0441\u043d\u0451\u0442\u0441\u044f, \u0441\u043d\u043e\u0432\u0430 \u043f\u043e\u0438\u0449\u0435\u0442 \u0438 \u043d\u0430\u0439\u0434\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">tarantool&gt; do     box.space.queue:truncate()     fiber.create(function()         fiber.sleep(0.1)         queue.put(&quot;task 3&quot;)     end)     local start = fiber.time()     return queue.take(3), { wait = fiber.time() - start } end  --- - [1594326905489650533, 'T', ['task 3']] - wait: 3.0017817020416 ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b <code>take<\/code> \u043f\u0440\u043e\u0441\u044b\u043f\u0430\u043b\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u0441\u0442\u0430\u0440\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>put<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0435\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u0430\u043d\u0430\u043b. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u043f\u0443\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 <code>true<\/code>. <\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u043d\u0435\u0435 \u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b, \u0447\u0442\u043e <code>put<\/code> \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0432 \u043a\u0430\u043d\u0430\u043b\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u0435\u0441\u0442\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044e \u0437\u0430\u0434\u0430\u0447 \u043d\u0435 \u0432\u0430\u0436\u043d\u043e, \u0435\u0441\u0442\u044c \u0441 \u0442\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0438\u043b\u0438 \u043d\u0435\u0442. \u041e\u043d \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443. \u0415\u0441\u043b\u0438 \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0435, \u043a\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435, \u043c\u044b \u0435\u0433\u043e \u0440\u0430\u0437\u0431\u0443\u0434\u0438\u043c. \u0418\u043d\u0430\u0447\u0435 \u0443 \u043d\u0430\u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u044d\u0442\u043e\u0442 \u043a\u0430\u043d\u0430\u043b \u043d\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0441\u044f. \u0418\u043b\u0438, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0435\u0441\u0442\u044c \u043b\u0438 \u0443 \u043a\u0430\u043d\u0430\u043b\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.put(...)     local id = gen_id()      if queue._wait:has_readers() then         queue._wait:put(true,0)     end      return box.space.queue:insert{ id, STATUS.READY, { ... } } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0434 <code>take<\/code> \u043d\u0430\u0447\u043d\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0438\u043d\u0430\u0447\u0435. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u0447\u0435\u0440\u0435\u0437 0,1 \u0441. \u0438 <code>take<\/code> \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043f\u0440\u043e\u0441\u044b\u043f\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0435\u0451. \u041c\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0442 \u0433\u043e\u0440\u044f\u0447\u0435\u0433\u043e \u0446\u0438\u043a\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0432\u0438\u0441\u0435\u043b \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0443, \u0442\u043e \u0444\u0430\u0439\u0431\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0436\u0434\u0430\u0442\u044c \u0442\u0440\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">tarantool&gt; do     box.space.queue:truncate()     fiber.create(function()         fiber.sleep(0.1)         queue.put(&quot;task 4&quot;)     end)     local start = fiber.time()     return queue.take(3), { wait = fiber.time() - start } end  --- - [1594327004302379957, 'T', ['task 4']] - wait: 0.10164666175842 ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043f\u043e \u0441\u0435\u0442\u0438. \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 <code>init.lua<\/code> \u0432 <code>box.cfg<\/code> \u043e\u043f\u0446\u0438\u044e <code>listen<\/code> \u2014 \u043f\u043e\u0440\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0448\u0430\u0442\u044c. \u0412\u043c\u0435\u0441\u0442\u0435 \u0441 \u044d\u0442\u0438\u043c \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0439, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043b\u044e\u0431\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043c\u0435\u043b\u043e \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. \u041f\u0440\u043e \u043f\u0440\u0430\u0432\u0430 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/www.tarantool.io\/en\/doc\/latest\/book\/box\/authentication\/\">\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e<\/a>. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on() fiber = require 'fiber'  box.cfg{     listen = '127.0.0.1:3301' } box.schema.user.grant('guest', 'super', nil, nil, { if_not_exists = true })  queue = require 'queue'  require'console'.start() os.exit()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442-<code>producer<\/code> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447. \u0412 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0435 Tarantool \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u0434\u0440\u0443\u0433\u043e\u043c\u0443 Tarantool.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">#!\/usr\/bin\/env tarantool  if #arg &lt; 1 then     error(&quot;Need arguments&quot;,0) end  local netbox = require 'net.box' local conn = netbox.connect('127.0.0.1:3301')  local yaml = require 'yaml' local res = conn:call('queue.put',{unpack(arg)}) print(yaml.encode(res)) conn:close()<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ tarantool producer.lua &quot;hi&quot; --- [1594327270675788959, 'R', ['hi']] ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c (<code>consumer<\/code>) \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>take<\/code> \u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0415\u0441\u043b\u0438 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0442\u043e \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u0435\u0451 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0442\u044c. \u041c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">#!\/usr\/bin\/env tarantool  local netbox = require 'net.box' local conn = netbox.connect('127.0.0.1:3301') local yaml = require 'yaml'  while true do     local task = conn:call('queue.take', { 1 })      if task then         print(&quot;Got task: &quot;, yaml.encode(task))         conn:call('queue.release', { task.id })     else         print &quot;No more tasks&quot;     end end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0444\u0438\u0433\u043d\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ tarantool consumer.lua  Got task:         --- [1594327270675788959, 'T', ['hi']] ...  ER_EXACT_MATCH: Invalid key part count in an exact match (expected 1, got 0)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f. \u041f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u043c\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043e\u043d \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u0437\u044f\u043b, \u043d\u043e \u043d\u0435 \u0441\u043c\u043e\u0433 \u0432\u0435\u0440\u043d\u0443\u0442\u044c: \u0443 \u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0441\u0442\u0440\u044f\u043b\u0430. \u0422\u0430\u043a\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u044f\u0442\u044c, \u043d\u043e \u0438 \u043d\u0435\u043a\u043e\u043c\u0443 \u0438\u0445 \u0432\u0435\u0440\u043d\u0443\u0442\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0445 \u0431\u0440\u0430\u043b, \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ tarantool consumer.lua  No more tasks No more tasks<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>select<\/code> \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u0432\u0437\u044f\u0442\u044b. <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; box.space.queue:select() --- - - [1594327004302379957, 'T', ['task 3']]   - [1594327270675788959, 'T', ['hi']] ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u043f\u0440\u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u0412 Tarantool \u0435\u0441\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u0445 \u0434\u043e\u0431\u0430\u0432\u0438\u043c, \u0442\u043e \u0441\u043c\u043e\u0436\u0435\u043c \u043e \u0444\u0430\u043a\u0442\u0430\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local log = require 'log'  box.session.on_connect(function()     log.info( &quot;connected %s from %s&quot;, box.session.id(), box.session.peer() ) end)  box.session.on_disconnect(function()     log.info( &quot;disconnected %s from %s&quot;, box.session.id(), box.session.peer() ) end) <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"plaintext\">2020-07-09 20:52:09.107 [32604] main\/115\/main I&gt; connected 2 from 127.0.0.1:36652 2020-07-09 20:52:10.260 [32604] main\/116\/main I&gt; disconnected 2 from nil 2020-07-09 20:52:10.823 [32604] main\/116\/main I&gt; connected 3 from 127.0.0.1:36654 2020-07-09 20:52:11.541 [32604] main\/115\/main I&gt; disconnected 3 from nil<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 <code>session id<\/code>, \u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c, \u0441 \u043a\u0430\u043a\u043e\u0433\u043e IP \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u041f\u0440\u0430\u0432\u0434\u0430, \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u044e\u0430\u043d\u0441. \u0412\u044b\u0437\u043e\u0432 <code>session.peer()<\/code> \u043f\u043e \u0441\u0443\u0442\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>getpeername(2)<\/code> \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430 \u0441\u043e\u043a\u0435\u0442\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043c\u044b \u0443\u0436\u0435 \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u043a\u0442\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f (<code>getpeername<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0437\u0430\u043a\u0440\u044b\u0442\u043e\u043c \u0441\u043e\u043a\u0435\u0442\u0435). C\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0445\u0430\u043a. \u0412 Tarantool \u0435\u0441\u0442\u044c <code>box.session.storage<\/code> \u2014 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432\u0441\u0451, \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0441\u0441\u0438\u0438. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0442\u043e \u043a \u043d\u0430\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0442\u044c, \u043a\u0442\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u0441\u044f. \u042d\u0442\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u043e\u0442\u043b\u0430\u0434\u043a\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.session.on_connect(function()     box.session.storage.peer = box.session.peer()     log.info( &quot;connected %s from %s&quot;, box.session.id(), box.session.storage.peer ) end)  box.session.on_disconnect(function()     log.info( &quot;disconnected %s from %s&quot;, box.session.id(), box.session.storage.peer ) end)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0432\u0437\u044f\u0442\u044b\u0435 \u0438\u043c \u0437\u0430\u0434\u0430\u0447\u0438. \u0412\u0432\u0435\u0434\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u00ab\u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0435\u0439\u00bb. \u0422\u0430 \u0441\u0435\u0441\u0441\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0437\u044f\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0443, \u0434\u043e\u043b\u0436\u043d\u0430 \u0437\u0430 \u043d\u0435\u0451 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c. \u0417\u0430\u0432\u0435\u0434\u0435\u043c \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>take<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">queue.taken = {}; -- \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0437\u044f\u0442\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 queue.bysid = {}; -- \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0434\u0430\u0447 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.take(timeout)     if not timeout then timeout = 0 end     local now = fiber.time()     local found     while not found do         found = box.space.queue.index.status             :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)         if not found then             local left = (now + timeout) - fiber.time()             if left &lt;= 0 then return end             queue._wait:get(left)         end     end      local sid = box.session.id()     log.info(&quot;Register %s by %s&quot;, found.id, sid)     queue.taken[ found.id ] = sid     queue.bysid[ sid ] = queue.bysid[ sid ] or {}     queue.bysid[ sid ][ found.id ] = true      return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }}) end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u0432 \u043d\u0435\u0439 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0432\u0437\u044f\u0442\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0435\u0439. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0437\u0430\u0434\u0430\u0447, <code>ack<\/code> \u0438 <code>release<\/code>. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0434\u043d\u0443 \u043e\u0431\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u0411\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0435\u0441\u0442\u044c \u0438 \u0432\u0437\u044f\u0442\u0430, \u043f\u0440\u0438\u0447\u0451\u043c \u0432\u0437\u044f\u0442\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0435\u0439. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0432\u0437\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u0430 \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u0440\u0438\u0439\u0442\u0438 \u0438 \u0441\u043a\u0430\u0437\u0430\u0442\u044c: \u00ab\u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0435\u0451, \u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u00bb. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local function get_task( id )     if not id then error(&quot;Task id required&quot;, 2) end     local t = box.space.queue:get{id}     if not t then         error(string.format( &quot;Task {%s} was not found&quot;, id ), 2)     end     if not queue.taken[id] then         error(string.format( &quot;Task %s not taken by anybody&quot;, id ), 2)     end     if queue.taken[id] ~= box.session.id() then         error(string.format( &quot;Task %s taken by %d. Not you (%d)&quot;,             id, queue.taken[id], box.session.id() ), 2)     end     return t end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>ack<\/code> \u0438 <code>release<\/code> \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438. \u041c\u044b \u0432 \u043d\u0438\u0445 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>get_task<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043d\u0430\u043c \u0438 \u0432\u0437\u044f\u0442\u0430. \u0418 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443\u0436\u0435 \u0441 \u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.ack(id)     local t = get_task(id)     queue.taken[ t.id ] = nil     queue.bysid[ box.session.id() ][ t.id ] = nil     return box.space.queue:delete{t.id} end  function queue.release(id)     local t = get_task(id)     if queue._wait:has_readers() then queue._wait:put(true,0) end     queue.taken[ t.id ] = nil     queue.bysid[ box.session.id() ][ t.id ] = nil     return box.space.queue         :update({t.id},{{'=', F.status, STATUS.READY }}) end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 <code>R<\/code> \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f SQL \u0438\u043b\u0438 Lua-c\u043d\u0438\u043f\u043f\u0435\u0442\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">box.execute[[ update &quot;queue&quot; set &quot;status&quot; = 'R' where &quot;status&quot; = 'T' ]] box.space.queue.index.status:pairs({'T'}):each(function(t) box.space.queue:update({t.id},{{'=',2,'R'}}) end)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u0437\u043e\u0432\u0435\u043c <code>consumer<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u043e\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u0442 <code>task ID required<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ tarantool consumer.lua  Got task:         --- [1594327004302379957, 'T', ['task 3']] ...  ER_PROC_LUA: queue.lua:113: Task id required<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u0434\u0435. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0438 Tarantool, \u043a\u043e\u0440\u0442\u0435\u0436 \u0432\u0441\u0435\u0433\u0434\u0430 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d \u0441\u043e \u0441\u043f\u0435\u0439\u0441\u043e\u043c. \u0423 \u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442, \u0430 \u0443 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u043b\u0435\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0442\u0430\u043f\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u0435\u043d\u0430\u043c\u0438 \u043f\u043e\u043b\u0435\u0439. \u0410 \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u043d\u043e\u0441\u0438\u043c \u044d\u0442\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0431\u0430\u0437\u044b, \u0442\u0430\u043f\u043b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u0435\u0439. \u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0431\u0443\u0434\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043d\u0435 \u0442\u0430\u043f\u043b\u044b, \u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u0438\u043c\u0435\u043d\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>:tomap{ names_only = true }<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.put(...)     --- ...     return box.space.queue         :insert{ id, STATUS.READY, { ... } }         :tomap{ names_only = true } end  function queue.take(timeout)     --- ...     return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }})         :tomap{ names_only = true } end  function queue.ack(id)     --- ...     return box.space.queue:delete{t.id}:tomap{ names_only = true } end  function queue.release(id)     --- ...     return box.space.queue         :update({t.id},{{'=', F.status, STATUS.READY }})         :tomap{ names_only = true } end  return queue<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043c\u0435\u043d\u044f\u0432 \u044d\u0442\u043e, \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u043c\u0441\u044f \u0441 \u043d\u043e\u0432\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ tarantool consumer.lua  Got task:         --- {'status': 'T', 'data': ['hi'], 'id': 1594327270675788959} ...  ER_PROC_LUA: queue.lua:117: Task 1594327270675788959ULL not taken by anybody<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0442\u0432\u0435\u0442\u0438\u0442, \u043c\u044b \u0435\u0451 \u043d\u0435 \u0431\u0440\u0430\u043b\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e ID \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435. \u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0441\u0443\u0444\u0444\u0438\u043a\u0441 ULL. <\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0434\u043d\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f LuaJIT: FFI (Foreign Function Interface). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0435\u0435. \u041f\u043e\u043b\u043e\u0436\u0438\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0435\u0439 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0437\u0430\u043f\u0438\u0441\u0438 \u0447\u0438\u0441\u043b\u0430 <code>1<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; t = {} tarantool&gt; t[1] = 1 tarantool&gt; t[&quot;1&quot;] = 2 tarantool&gt; t[1LL] = 3 tarantool&gt; t[1ULL] = 4 tarantool&gt; t[1ULL] = 5 tarantool&gt; t --- - 1: 1   1: 5   1: 4   '1': 2   1: 3 ... <\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u043e\u043b\u043e\u0436\u0430\u0442\u0441\u044f \u043a\u0430\u043a <code>2<\/code> (\u0441\u0442\u0440\u043e\u043a\u0430 + \u0447\u0438\u0441\u043b\u043e). \u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043a\u0430\u043a <code>3<\/code> (\u0441\u0442\u0440\u043e\u043a\u0430, \u0447\u0438\u0441\u043b\u043e, LL). \u041d\u043e \u043f\u0440\u0438 \u0432\u044b\u0432\u043e\u0434\u0435 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0435 \u043a\u043b\u044e\u0447\u0438 \u043b\u0435\u0436\u0430\u0442 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044c\u043d\u043e: \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>1<\/code>, <code>2<\/code>, <code>3<\/code>, <code>4<\/code>, <code>5<\/code>. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438, \u0437\u043d\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u0438 \u0431\u0435\u0437\u0437\u043d\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u0447\u0438\u0441\u043b\u0430\u043c\u0438. <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; return t[1], t['1'], t[1LL], t[1ULL] --- - 1 - 2 - null - null ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u0441\u0430\u043c\u043e\u0435 \u0432\u0435\u0441\u0435\u043b\u044c\u0435 \u043d\u0430\u0441\u0442\u0443\u043f\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0421 \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438 Lua-\u0442\u0438\u043f\u0430\u043c\u0438 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e (<code>number<\/code> \u0438 <code>string<\/code>), \u0430 \u0432\u043e\u0442 \u0441 LL (<code>long long<\/code>) \u0438 ULL (<code>unsigned long long<\/code>) \u2014 \u043d\u0435\u0442. \u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c <code>cdata<\/code>. \u041e\u043d \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0438\u0437 \u044f\u0437\u044b\u043a\u0430 C. \u0418 \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0432 Lua-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>cdata<\/code> \u0445\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443, \u0430 \u043d\u0435 \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e. \u0423 \u0434\u0432\u0443\u0445, \u043f\u0443\u0441\u0442\u044c \u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u0447\u0438\u0441\u0435\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u0430. \u0418 \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c ULL \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0442\u043e \u043f\u043e\u0442\u043e\u043c \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0448\u0443 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0428\u0430\u0433 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u043a\u043b\u044e\u0447\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u043a\u043b\u044e\u0447 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u043b\u0438 \u0447\u0438\u0441\u043b\u043e. \u0412\u043e\u0437\u044c\u043c\u0435\u043c MessagePack. \u0412 Tarantool \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u043f\u043b\u043e\u0432 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0430\u043c Tarantool. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043a\u043b\u044e\u0447\u043e\u043c \u0432 \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local msgpack = require 'msgpack'  local function keypack( key )     return msgpack.encode( key ) end  local function keyunpack( data )     return msgpack.decode( data ) end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <code>take<\/code> \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>get_task<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u043f\u0440\u043e\u0448\u0435\u043b \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0438 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a, \u0442\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c \u0435\u0433\u043e \u0432 <code>int64<\/code>. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0442\u0435\u043c \u0436\u0435 \u0441\u0430\u043c\u044b\u043c <code>keypack<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043f\u0430\u043a\u0443\u0435\u0442 \u043a\u043b\u044e\u0447 \u0432 MessagePack. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e\u0442 \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0437 <code>get_task<\/code>, \u0447\u0442\u043e\u0431\u044b <code>ack<\/code> \u0438 <code>release<\/code> \u043c\u043e\u0433\u043b\u0438 \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0432\u044b\u0447\u0438\u0449\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u0441\u0435\u0441\u0441\u0438\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.take(timeout)     if not timeout then timeout = 0 end     local now = fiber.time()     local found     while not found do         found = box.space.queue.index.status             :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)         if not found then             local left = (now + timeout) - fiber.time()             if left &lt;= 0 then return end             queue._wait:get(left)         end     end      local sid = box.session.id()     log.info(&quot;Register %s by %s&quot;, found.id, sid)     local key = keypack( found.id )     queue.taken[ key ] = sid     queue.bysid[ sid ] = queue.bysid[ sid ] or {}     queue.bysid[ sid ][ key ] = true      return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }})         :tomap{ names_only = true } end  local function get_task( id )     if not id then error(&quot;Task id required&quot;, 2) end     id = tonumber64(id)     local key = keypack(id)     local t = box.space.queue:get{id}     if not t then         error(string.format( &quot;Task {%s} was not found&quot;, id ), 2)     end     if not queue.taken[key] then         error(string.format( &quot;Task %s not taken by anybody&quot;, id ), 2)     end     if queue.taken[key] ~= box.session.id() then         error(string.format( &quot;Task %s taken by %d. Not you (%d)&quot;,             id, queue.taken[key], box.session.id() ), 2)     end     return t, key end  function queue.ack(id)     local t, key = get_task(id)     queue.taken[ key ] = nil     queue.bysid[ box.session.id() ][ key ] = nil     return box.space.queue:delete{t.id}:tomap{ names_only = true } end  function queue.release(id)     local t, key = get_task(id)     queue.taken[ key ] = nil     queue.bysid[ box.session.id() ][ key ] = nil     if queue._wait:has_readers() then queue._wait:put(true,0) end     return box.space.queue         :update({t.id},{{'=', F.status, STATUS.READY }})         :tomap{ names_only = true } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0435\u0441\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u043d\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u0430\u0441\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0441\u0435\u0441\u0441\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u043a\u0430\u043a\u0438\u043c\u0438-\u0442\u043e \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u041c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0432\u0441\u0435 \u043a\u043b\u044e\u0447\u0438 \u044d\u0442\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u0445 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u2014 <code>ready<\/code>. \u0422\u0430\u043a\u0436\u0435, \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 <code>take<\/code>. \u041e\u0441\u0442\u0430\u0432\u0438\u043c \u0434\u043b\u044f \u043d\u0438\u0445 \u043c\u0430\u0440\u043a\u0435\u0440 \u0432 <code>session.storage<\/code>, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u0440\u0430\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.session.on_disconnect(function()     log.info( &quot;disconnected %s from %s&quot;, box.session.id(), box.session.storage.peer )     box.session.storage.destroyed = true      local sid = box.session.id()     local bysid = queue.bysid[ sid ]     if bysid then         while next(bysid) do             for key, id in pairs(bysid) do                 log.info(&quot;Autorelease %s by disconnect&quot;, id);                 queue.taken[key] = nil                 bysid[key] = nil                 local t = box.space.queue:get(id)                 if t then                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({t.id},{{'=', F.status, STATUS.READY }})                 end             end         end         queue.bysid[ sid ] = nil     end end)  function queue.take(timeout)     if not timeout then timeout = 0 end     local now = fiber.time()     local found     while not found do         found = box.space.queue.index.status             :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)         if not found then             local left = (now + timeout) - fiber.time()             if left &lt;= 0 then return end             queue._wait:get(left)         end     end      if box.session.storage.destroyed then return end      local sid = box.session.id()     log.info(&quot;Register %s by %s&quot;, found.id, sid)     local key = keypack( found.id )     queue.taken[ key ] = sid     queue.bysid[ sid ] = queue.bysid[ sid ] or {}     queue.bysid[ sid ][ key ] = found.id      return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }})         :tomap{ names_only = true } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0440\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantoolctl connect 127.0.0.1:3301 &lt;&lt;&lt; 'queue.take()' <\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043a\u0430 \u044d\u0442\u043e \u0432\u0441\u0451 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u043b\u043e\u0441\u044c, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u044b \u0432\u0437\u044f\u043b\u0438 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u043e\u0442\u0443\u0448\u0438\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0437\u0430\u043d\u043e\u0432\u043e \u2014 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0438\u043a\u043e\u043c\u0443 \u043d\u0435 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442 (\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438), \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d\u0438 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 <code>taken<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043a\u043e\u0434 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435: \u0431\u0430\u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u0437\u044f\u0442\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">while true do     local t = box.space.queue.index.status:pairs({STATUS.TAKEN}):nth(1)     if not t then break end     box.space.queue:update({ t.id }, {{'=', F.status, STATUS.READY }})     log.info(&quot;Autoreleased %s at start&quot;, t.id) end<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<h3 id=\"dobavim-otlozhennuyu-obrabotku\">\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443<\/h3>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438 \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e \u043d\u0435\u043c\u0443. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u043a\u043e\u0433\u0434\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. \u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>put<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441:<code>W=WAITING<\/code>. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space.queue:format( {     { name = 'id';     type = 'number' },     { name = 'status'; type = 'string' },     { name = 'runat';  type = 'number' },     { name = 'data';   type = '*'      }, } )  box.space.queue:create_index('runat', {     parts = { F.runat, 'number', F.id, 'number' };     if_not_exists = true; })  STATUS.WAITING = 'W'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044f\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0438 \u044d\u0442\u043e \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043e\u0447\u0438\u0441\u0442\u0438\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443 (\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438):<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space.queue.drop() box.snapshot()<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c.<\/p>\n<p>  <\/p>\n<p>\u0412 <code>put<\/code> \u0438 <code>release<\/code> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <code>delay<\/code>. \u0415\u0441\u043b\u0438 <code>delay<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u043d, \u0442\u043e \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>WAITING<\/code> \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0432 \u043a\u0430\u043a\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u043e\u043d\u043e\u0432\u044b\u043c\u0438 \u0444\u0430\u0439\u0431\u0435\u0440\u0430\u043c\u0438. \u0412 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u0431\u0435\u0440, \u043d\u0435 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0438 \u0441 \u043a\u0430\u043a\u0438\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\u043c \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0444\u043e\u043d\u0435. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u0431\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043a\u0440\u0443\u0442\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0438 \u0436\u0434\u0430\u0442\u044c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.put(data, opts)     local id = gen_id()      local runat = 0     local status = STATUS.READY      if opts and opts.delay then         runat = clock.realtime() + tonumber(opts.delay)         status = STATUS.WAITING     else         if queue._wait:has_readers() then             queue._wait:put(true,0)         end     end      return box.space.queue         :insert{ id, status, runat, data }         :tomap{ names_only=true } end  function queue.release(id, opts)     local t, key = get_task(id)     queue.taken[ key ] = nil     queue.bysid[ box.session.id() ][ key ] = nil      local runat = 0     local status = STATUS.READY      if opts and opts.delay then         runat = clock.realtime() + tonumber(opts.delay)         status = STATUS.WAITING     else         if queue._wait:has_readers() then queue._wait:put(true,0) end     end      return box.space.queue         :update({t.id},{{ '=', F.status, status },{ '=', F.runat, runat }})         :tomap{ names_only = true } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0438, \u043c\u044b \u0435\u0451 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c. \u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0438\u0437 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438, \u0442\u0430\u043a\u0436\u0435 \u043d\u043e\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044f \u0442\u0435\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0436\u0434\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443. <\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0430\u0434\u0451\u043c \u0437\u0430\u0434\u0430\u0447\u0443 \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>take<\/code>, \u0433\u043e\u0442\u043e\u0432\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0435\u0442. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u0443\u0436\u0435 \u0441 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d\u0430 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430\u0441\u043b\u0443\u0433\u0430 \u0444\u0430\u0439\u0431\u0435\u0440\u0430 <code>queue.runat<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">queue._runat = fiber.create(function()     fiber.name('queue.runat')     while true do         local remaining          local now = clock.realtime()         for _,t in box.space.queue.index.runat             :pairs( { 0 }, { iterator = 'GT' })         do             if t.runat &gt; now then                 remaining = t.runat - now                 break             else                 if t.status == STATUS.WAITING then                     log.info(&quot;Runat: W-&gt;R %s&quot;,t.id)                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({ t.id }, {                         {'=', F.status, STATUS.READY },                         {'=', F.runat, 0 },                     })                 else                     log.error(&quot;Runat: bad status %s for %s&quot;, t.status, t.id)                     box.space.queue:update({ t.id },{{ '=', F.runat, 0 }})                 end             end         end          if not remaining or remaining &gt; 1 then remaining = 1 end         fiber.sleep(remaining)     end end)<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"monitoring\">\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433<\/h3>\n<p>  <\/p>\n<p>\u041d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u043f\u0435\u0447\u0430\u043b\u044c\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u0448\u0435\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e: \u043e\u043d\u0430 \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439. \u0418\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0438\u0432\u043d\u043e \u0438 \u0432 \u043b\u043e\u0431 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0441 \u043d\u0430\u0448\u0435\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438: \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0441\u0442\u044c, \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">function queue.stats()     return {         total   = box.space.queue:len(),         ready   = box.space.queue.index.status:count({STATUS.READY}),         waiting = box.space.queue.index.status:count({STATUS.WAITING}),         taken   = box.space.queue.index.status:count({STATUS.TAKEN}),     }     end<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"plaintext\">tarantool&gt; queue.stats() --- - ready: 10   taken: 2   waiting: 5   total: 17 ...  tarantool&gt; local clock = require 'clock' local s = clock.time() local r = queue.stats() return r, clock.time() - s --- - ready: 10   taken: 2   waiting: 5   total: 17 - 0.00057339668273926 ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e. \u0414\u043e \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u043a\u0430 \u0437\u0430\u0434\u0430\u0447 \u043d\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e. \u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u2014 \u043f\u0443\u0441\u0442\u043e\u0435. \u041d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e-\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043b\u0435\u0442\u0430\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u0438\u043b\u043b\u0438\u043e\u043d \u0437\u0430\u0434\u0430\u0447. \u041d\u0430\u0448\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>stats<\/code> \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u0440\u0430\u0432\u0434\u0430, \u043e\u043d\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0432\u044b\u0437\u043e\u0432\u0435 <code>index:count<\/code> \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 full-scan \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u043e\u0432. <\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">queue._stats = {} for k,v in pairs(STATUS) do     queue._stats[v] = 0LL end  for _,t in box.space.queue:pairs() do     queue._stats[ t[F.status] ] = (queue._stats[ t[F.status] ] or 0LL)+1 end  function queue.stats()     return {         total   = box.space.queue:len(),         ready   = queue._stats[ STATUS.READY ],         waiting = queue._stats[ STATUS.WAITING ],         taken   = queue._stats[ STATUS.TAKEN ],     } end<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0430\u0447\u043d\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0438 \u043f\u0440\u0438 \u043b\u044e\u0431\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445. \u041f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c, \u0434\u0440\u0443\u0433\u043e\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c. \u041c\u043e\u0436\u043d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0430\u043f\u0434\u0435\u0439\u0442\u044b \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c, \u043d\u043e \u044d\u0442\u043e \u0447\u0440\u0435\u0432\u0430\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438 \u0438 \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f\u043c\u0438. \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e \u0432 Tarantool \u0435\u0441\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u043d\u0430 \u0441\u043f\u0435\u0439\u0441\u0430\u0445. \u0422\u0440\u0438\u0433\u0433\u0435\u0440 \u0432\u0438\u0434\u0438\u0442 \u043b\u044e\u0431\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432 \u0441\u043f\u0435\u0439\u0441\u0435. \u041c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>space:update<\/code> \u0438\u043b\u0438 <code>space:delete<\/code>, \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u044d\u0442\u043e \u0443\u0447\u0442\u0435\u0442 \u0438 \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0435\u0442. \u0422\u0440\u0438\u0433\u0433\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043e\u043d\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435. \u041f\u0440\u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0435 \u043c\u044b \u0435\u0434\u0438\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u043e \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u043e\u0432.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space.queue:on_replace(function(old,new)     if old then         queue._stats[ old[ F.status ] ] = queue._stats[ old[ F.status ] ] - 1     end     if new then         queue._stats[ new[ F.status ] ] = queue._stats[ new[ F.status ] ] + 1     end end)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435\u043b\u044c\u0437\u044f \u043e\u0442\u043b\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0441\u043f\u0435\u0439\u0441\u0435, \u043d\u043e \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435: <code>space:truncate()<\/code>. \u041e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0441\u043f\u0435\u0439\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0432 \u0441\u043f\u0435\u0439\u0441\u0435 \u2014 <code>_truncate<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">box.space._truncate:on_replace(function(old,new)     if new.id == box.space.queue.id then         for k,v in pairs(queue._stats) do             queue._stats[k] = 0LL         end     end end)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u0447\u043d\u043e \u0438 \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e. \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0441\u0435\u0442\u0438. \u0412\u043e\u043e\u0431\u0449\u0435 \u0432 Tarantool \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u043a\u0435\u0442\u044b. \u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e, \u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u043a \u0432 C.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043c\u0435\u0442\u0440\u0438\u043a \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 graphite \u043f\u043e UDP:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local socket = require 'socket' local errno = require 'errno'  local graphite_host = '127.0.0.1' local graphite_port = 2003  local ai = socket.getaddrinfo(graphite_host, graphite_port, 1, { type = 'SOCK_DGRAM' }) local addr,port for _,info in pairs(ai) do    addr,port = info.host,info.port    break end if not addr then error(&quot;Failed to resolve host&quot;) end  queue._monitor = fiber.create(function()     fiber.name('queue.monitor')     fiber.yield()     local remote = socket('AF_INET', 'SOCK_DGRAM', 'udp')     while true do         for k,v in pairs(queue.stats()) do             local msg = string.format(&quot;queue.stats.%s %s %s\\n&quot;, k, tonumber(v), math.floor(fiber.time()))             local res = remote:sendto(addr, port, msg)             if not res then                 log.error(&quot;Failed to send: %s&quot;, errno.strerror(errno()))             end         end         fiber.sleep(1)     end end)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438\u043b\u0438 \u043f\u043e TCP:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local socket = require 'socket' local errno = require 'errno'  local graphite_host = '127.0.0.1' local graphite_port = 2003  queue._monitor = fiber.create(function()     fiber.name('queue.monitor')     fiber.yield()     while true do         local remote =  require 'socket'.tcp_connect(graphite_host, graphite_port)         if not remote then             log.error(&quot;Failed to connect to graphite %s&quot;,errno.strerror())             fiber.sleep(1)         else             while true do                 local data = {}                 for k,v in pairs(queue.stats()) do                     table.insert(data,string.format(&quot;queue.stats.%s %s %s\\n&quot;,k,tonumber(v),math.floor(fiber.time())))                 end                 data = table.concat(data,'')                 if not remote:send(data) then                     log.error(&quot;%s&quot;,errno.strerror())                     break                 end                 fiber.sleep(1)             end         end     end end)<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"goryachaya-perezagruzka-koda\">\u0413\u043e\u0440\u044f\u0447\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u0434\u0430<\/h3>\n<p>  <\/p>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0435\u043b\u044c\u0437\u044f \u043d\u0435 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0432\u0430\u0436\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b Tarantool, \u043a\u0430\u043a \u0433\u043e\u0440\u044f\u0447\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u0434\u0430. \u0412 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0442\u0430\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0441\u0442\u043e\u043b\u044c \u0432\u043e\u0441\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0430, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0443 \u0432\u0430\u0441 \u0411\u0414 \u043d\u0430 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u044b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043b\u044e\u0431\u043e\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u043e\u0438\u0442\u044c \u0432\u0430\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u0443\u044e \u0441\u043b\u0443\u0436\u0431\u0443. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0433\u043e\u0440\u044f\u0447\u0435\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 Lua \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 <code>require<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0451\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <code>package.loaded<\/code> \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044f. \u041f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u044b <code>require<\/code> \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0444\u0430\u0439\u043b, \u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c Lua \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0435\u0433\u043e, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0435\u0440\u0435\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 <code>package.loaded[...]<\/code> \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>require<\/code>. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e \u0441\u0430\u043c\u0438\u043c \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0441\u043d\u0438\u043f\u043f\u0435\u0442 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u043b\u043e\u0430\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on() fiber = require 'fiber'  box.cfg{     listen = '127.0.0.1:3301' } box.schema.user.grant('guest', 'super', nil, nil, { if_not_exists = true })  local not_first_run = rawget(_G,'_NOT_FIRST_RUN') _NOT_FIRST_RUN = true if not_first_run then    for k,v in pairs(package.loaded) do       if not preloaded[k] then          package.loaded[k] = nil       end    end else    preloaded = {}    for k,v in pairs(package.loaded) do       preloaded[k] = true    end end  queue = require 'queue'  require'console'.start() os.exit()<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0440\u0435\u043b\u043e\u0430\u0434 \u043a\u043e\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0438\u043f\u0438\u0447\u043d\u043e\u0439 \u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <a href=\"https:\/\/github.com\/moonlibs\/package-reload\">package.reload<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0432 \u043f\u043e\u0434\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041e\u043d \u0441\u0430\u043c \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442, \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432\u0441\u0451 \u0431\u044b\u043b\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e, \u043a\u0430\u043a\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u0435\u0434\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438: <code>package.reload()<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on() fiber = require 'fiber'  box.cfg{     listen = '127.0.0.1:3301' } box.schema.user.grant('guest', 'super', nil, nil, { if_not_exists = true })  require 'package.reload'  queue = require 'queue'  require'console'.start() os.exit()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u043a\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u041f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u044b \u2014 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local queue = {} local old = rawget(_G,'queue') if old then     queue.taken = old.taken     queue.bysid = old.bysid     queue._triggers = old._triggers     queue._stats = old._stats     queue._wait = old._wait     queue._runch = old._runch     queue._runat = old._runat else     queue.taken = {}     queue.bysid = {}     queue._triggers = {}     queue._stats = {}     queue._wait = fiber.channel()     queue._runch = fiber.cond()     while true do         local t = box.space.queue.index.status:pairs({STATUS.TAKEN}):nth(1)         if not t then break end         box.space.queue:update({ t.id }, {{'=', F.status, STATUS.READY }})         log.info(&quot;Autoreleased %s at start&quot;, t.id)     end     for k,v in pairs(STATUS) do         queue._stats[v] = 0LL     end     for _,t in box.space.queue:pairs() do         queue._stats[ t[F.status] ] = (queue._stats[ t[F.status] ] or 0LL)+1     end     log.info(&quot;Perform initial stat counts %s&quot;, box.tuple.new{ queue._stats }) end <\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432. \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u0431\u044b\u043b\u043e, \u0442\u043e \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430. \u041d\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0451. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0451 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440. \u041f\u0440\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u0445 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">queue._triggers.on_replace = box.space.queue:on_replace(function(old,new)     if old then         queue._stats[ old[ F.status ] ] = queue._stats[ old[ F.status ] ] - 1     end     if new then         queue._stats[ new[ F.status ] ] = queue._stats[ new[ F.status ] ] + 1     end end, queue._triggers.on_replace)  queue._triggers.on_truncate = box.space._truncate:on_replace(function(old,new)     if new.id == box.space.queue.id then         for k,v in pairs(queue._stats) do             queue._stats[k] = 0LL         end     end end, queue._triggers.on_truncate)  queue._triggers.on_connect = box.session.on_connect(function()     box.session.storage.peer = box.session.peer()     log.info( &quot;connected %s from %s&quot;, box.session.id(), box.session.storage.peer ) end, queue._triggers.on_connect)  queue._triggers.on_disconnect = box.session.on_disconnect(function()     log.info( &quot;disconnected %s from %s&quot;, box.session.id(), box.session.storage.peer )     box.session.storage.destroyed = true      local sid = box.session.id()     local bysid = queue.bysid[ sid ]     if bysid then         while next(bysid) do             for key, id in pairs(bysid) do                 log.info(&quot;Autorelease %s by disconnect&quot;, id);                 queue.taken[key] = nil                 bysid[key] = nil                 local t = box.space.queue:get(id)                 if t then                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({t.id},{{'=', F.status, STATUS.READY }})                 end             end         end         queue.bysid[ sid ] = nil     end end, queue._triggers.on_disconnect)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u0430\u0436\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u2014 \u044d\u0442\u043e \u0444\u0430\u0439\u0431\u0435\u0440\u044b. \u0424\u0430\u0439\u0431\u0435\u0440 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u043d\u0435, \u043c\u044b \u0435\u0433\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c. \u0412 \u043d\u0451\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e <code>while ... true<\/code>, \u043e\u043d \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0438 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043d\u0438\u043c, \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u0430\u043d\u0430\u043b, \u0430 \u0435\u0449\u0451 \u043b\u0443\u0447\u0448\u0435 <code>fiber.cond<\/code>: condition variable, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u0444\u0430\u0439\u0431\u0435\u0440\u0430\u043c.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u0430\u0439\u0431\u0435\u0440\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u044b\u0437\u043e\u0432\u0430 <code>fiber.kill<\/code>, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0435\u043d: \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>kill<\/code> \u0432 \u043d\u0435\u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043c\u044b \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u0431\u0435\u0440\u0430: \u0444\u0430\u0439\u0431\u0435\u0440 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043a\u043e\u0434\u0430 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u0444\u0430\u0439\u0431\u0435\u0440 \u0447\u0438\u0441\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u0430\u0439\u0431\u0435\u0440\u043e\u0432: \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u0442\u0430\u0442\u0443\u0441 \u0444\u0430\u0439\u0431\u0435\u0440\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">queue._runat = fiber.create(function(queue, gen, old_fiber)     fiber.name('queue.runat.'..gen)      while package.reload.count == gen and old_fiber and old_fiber:status() ~= 'dead' do         log.info(&quot;Waiting for old to die&quot;)         queue._runch:wait(0.1)     end      log.info(&quot;Started...&quot;)     while package.reload.count == gen do         local remaining          local now = clock.realtime()          for _,t in box.space.queue.index.runat             :pairs( {0}, { iterator = 'GT' })         do             if t.runat &gt; now then                 remaining = t.runat - now                 break             else                 if t.status == STATUS.WAITING then                     log.info(&quot;Runat: W-&gt;R %s&quot;,t.id)                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({ t.id }, {                         { '=', F.status, STATUS.READY },                         { '=', F.runat, 0 },                     })                 else                     log.error(&quot;Runat: bad status %s for %s&quot;, t.status, t.id)                     box.space.queue:update({ t.id },{{ '=', F.runat, 0 }})                 end             end         end          if not remaining or remaining &gt; 1 then remaining = 1 end         queue._runch:wait(remaining)     end      queue._runch:broadcast()     log.info(&quot;Finished&quot;) end, queue, package.reload.count, queue._runat) queue._runch:broadcast()<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a: \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043a\u043e\u0434\u0430 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430, \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0443\u0436\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">if not fiber.self().storage.console then     require'console'.start()     os.exit() end<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"podvedem-itog\">\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433<\/h3>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0443\u044e \u0441\u0435\u0442\u0435\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0441 \u0430\u0432\u0442\u043e\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043e\u043c \u0437\u0430\u0434\u0430\u0447 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432, \u0441 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432 Graphite \u043f\u043e TCP, \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u043d\u044e\u0430\u043d\u0441\u043e\u0432. \u041d\u0430 \u0441\u0440\u0435\u0434\u043d\u0435\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u0436\u0435\u043b\u0435\u0437\u0435 \u0442\u0430\u043a\u0430\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432\u044b\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043e\u0442 20 \u0442\u044b\u0441. \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443. \u041e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0438\u0437 300 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430 \u0438 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0437\u0430 \u0434\u0435\u043d\u044c \u0441 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u0439\u043b\u044b<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p><code>queue.lua<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">local clock = require 'clock' local errno = require 'errno' local fiber = require 'fiber' local log = require 'log' local msgpack = require 'msgpack' local socket = require 'socket'  box.schema.create_space('queue',{ if_not_exists = true; })  box.space.queue:format( {     { name = 'id';     type = 'number' },     { name = 'status'; type = 'string' },     { name = 'runat';  type = 'number' },     { name = 'data';   type = '*'      }, } );  local F = {} for no,def in pairs(box.space.queue:format()) do     F[no] = def.name     F[def.name] = no end  box.space.queue:create_index('primary', {    parts = { F.id, 'number' };    if_not_exists = true; })  box.space.queue:create_index('status', {     parts = { F.status, 'string', F.id, 'number' };     if_not_exists = true; })  box.space.queue:create_index('runat', {     parts = { F.runat, 'number', F.id, 'number' };     if_not_exists = true; })  local STATUS = {} STATUS.READY = 'R' STATUS.TAKEN = 'T' STATUS.WAITING = 'W'  local queue = {} local old = rawget(_G,'queue') if old then     queue.taken = old.taken     queue.bysid = old.bysid     queue._triggers = old._triggers     queue._stats = old._stats     queue._wait = old._wait     queue._runch = old._runch     queue._runat = old._runat else     queue.taken = {}     queue.bysid = {}     queue._triggers = {}     queue._stats = {}     queue._wait = fiber.channel()     queue._runch = fiber.cond()     while true do         local t = box.space.queue.index.status:pairs({STATUS.TAKEN}):nth(1)         if not t then break end         box.space.queue:update({ t.id }, {{'=', F.status, STATUS.READY }})         log.info(&quot;Autoreleased %s at start&quot;, t.id)     end      for k,v in pairs(STATUS) do queue._stats[v] = 0LL end     for _,t in box.space.queue:pairs() do         queue._stats[ t[F.status] ] = (queue._stats[ t[F.status] ] or 0LL)+1     end     log.info(&quot;Perform initial stat counts %s&quot;, box.tuple.new{ queue._stats }) end  local function gen_id()     local new_id     repeat         new_id = clock.realtime64()     until not box.space.queue:get(new_id)     return new_id end  local function keypack( key )     return msgpack.encode( key ) end  local function keyunpack( data )     return msgpack.decode( data ) end  queue._triggers.on_replace = box.space.queue:on_replace(function(old,new)     if old then         queue._stats[ old[ F.status ] ] = queue._stats[ old[ F.status ] ] - 1     end     if new then         queue._stats[ new[ F.status ] ] = queue._stats[ new[ F.status ] ] + 1     end end, queue._triggers.on_replace)  queue._triggers.on_truncate = box.space._truncate:on_replace(function(old,new)     if new.id == box.space.queue.id then         for k,v in pairs(queue._stats) do             queue._stats[k] = 0LL         end     end end, queue._triggers.on_truncate)  queue._triggers.on_connect = box.session.on_connect(function()     box.session.storage.peer = box.session.peer() end, queue._triggers.on_connect)  queue._triggers.on_disconnect = box.session.on_disconnect(function()     box.session.storage.destroyed = true     local sid = box.session.id()     local bysid = queue.bysid[ sid ]     if bysid then         log.info( &quot;disconnected %s from %s&quot;, box.session.id(), box.session.storage.peer )         while next(bysid) do             for key, id in pairs(bysid) do                 log.info(&quot;Autorelease %s by disconnect&quot;, id);                 queue.taken[key] = nil                 bysid[key] = nil                 local t = box.space.queue:get(id)                 if t then                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({t.id},{{'=', F.status, STATUS.READY }})                 end             end         end         queue.bysid[ sid ] = nil     end end, queue._triggers.on_disconnect)  queue._runat = fiber.create(function(queue, gen, old_fiber)     fiber.name('queue.runat.'..gen)      while package.reload.count == gen and old_fiber and old_fiber:status() ~= 'dead' do         log.info(&quot;Waiting for old to die&quot;)         queue._runch:wait(0.1)     end      log.info(&quot;Started...&quot;)     while package.reload.count == gen do         local remaining          local now = clock.realtime()          for _,t in box.space.queue.index.runat             :pairs( {0}, { iterator = 'GT' })         do             if t.runat &gt; now then                 remaining = t.runat - now                 break             else                 if t.status == STATUS.WAITING then                     log.info(&quot;Runat: W-&gt;R %s&quot;,t.id)                     if queue._wait:has_readers() then queue._wait:put(true,0) end                     box.space.queue:update({ t.id }, {                         { '=', F.status, STATUS.READY },                         { '=', F.runat, 0 },                     })                 else                     log.error(&quot;Runat: bad status %s for %s&quot;, t.status, t.id)                     box.space.queue:update({ t.id },{{ '=', F.runat, 0 }})                 end             end         end          if not remaining or remaining &gt; 1 then remaining = 1 end         queue._runch:wait(remaining)     end      queue._runch:broadcast()     log.info(&quot;Finished&quot;) end, queue, package.reload.count, queue._runat) queue._runch:broadcast()  local graphite_host = '127.0.0.1' local graphite_port = 2003 queue._monitor = fiber.create(function(gen)     fiber.name('queue.mon.'..gen)     fiber.yield()     while package.reload.count == gen do         local remote =  require 'socket'.tcp_connect(graphite_host, graphite_port)         if not remote then             log.error(&quot;Failed to connect to graphite %s&quot;,errno.strerror())             fiber.sleep(1)         else             while package.reload.count == gen do                 local data = {}                 for k,v in pairs(queue.stats()) do                     table.insert(data,string.format(&quot;queue.stats.%s %s %s\\n&quot;,k,tonumber(v),math.floor(fiber.time())))                 end                 data = table.concat(data,'')                 if not remote:send(data) then                     log.error(&quot;%s&quot;,errno.strerror())                     break                 end                 fiber.sleep(1)             end         end     end end, package.reload.count)  function queue.put(data, opts)     local id = gen_id()      local runat = 0     local status = STATUS.READY     if opts and opts.delay then         runat = clock.realtime() + tonumber(opts.delay)         status = STATUS.WAITING     else         if queue._wait:has_readers() then             queue._wait:put(true,0)         end     end      return box.space.queue         :insert{ id, status, runat, data }         :tomap{ names_only=true } end  function queue.take(timeout)     if not timeout then timeout = 0 end     local now = fiber.time()     local found     while not found do         found = box.space.queue.index.status             :pairs({STATUS.READY},{ iterator = 'EQ' }):nth(1)         if not found then             local left = (now + timeout) - fiber.time()             if left &lt;= 0 then return end             queue._wait:get(left)         end     end      if box.session.storage.destroyed then return end      local sid = box.session.id()     log.info(&quot;Register %s by %s&quot;, found.id, sid)     local key = keypack( found.id )     queue.taken[ key ] = sid     queue.bysid[ sid ] = queue.bysid[ sid ] or {}     queue.bysid[ sid ][ key ] = found.id      return box.space.queue         :update( {found.id}, {{'=', F.status, STATUS.TAKEN }})         :tomap{ names_only = true } end  local function get_task( id )     if not id then error(&quot;Task id required&quot;, 2) end     id = tonumber64(id)     local key = keypack(id)     local t = box.space.queue:get{id}     if not t then         error(string.format( &quot;Task {%s} was not found&quot;, id ), 2)     end     if not queue.taken[key] then         error(string.format( &quot;Task %s not taken by anybody&quot;, id ), 2)     end     if queue.taken[key] ~= box.session.id() then         error(string.format( &quot;Task %s taken by %d. Not you (%d)&quot;,             id, queue.taken[key], box.session.id() ), 2)     end     return t, key end  function queue.ack(id)     local t, key = get_task(id)     queue.taken[ key ] = nil     queue.bysid[ box.session.id() ][ key ] = nil     return box.space.queue:delete{t.id}:tomap{ names_only = true } end  function queue.release(id, opts)     local t, key = get_task(id)     queue.taken[ key ] = nil     queue.bysid[ box.session.id() ][ key ] = nil      local runat = 0     local status = STATUS.READY      if opts and opts.delay then         runat = clock.realtime() + tonumber(opts.delay)         status = STATUS.WAITING     else         if queue._wait:has_readers() then queue._wait:put(true,0) end     end      return box.space.queue         :update({t.id},{{'=', F.status, status },{ '=', F.runat, runat }})         :tomap{ names_only = true } end  function queue.stats()     return {         total   = box.space.queue:len(),         ready   = queue._stats[ STATUS.READY ],         waiting = queue._stats[ STATUS.WAITING ],         taken   = queue._stats[ STATUS.TAKEN ],     } end  return queue<\/code><\/pre>\n<p>  <\/p>\n<p><code>init.lua<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"lua\">require'strict'.on() fiber = require 'fiber' require 'package.reload'  box.cfg{     listen = '127.0.0.1:3301' } box.schema.user.grant('guest', 'super', nil, nil, { if_not_exists = true })  queue = require 'queue'  if not fiber.self().storage.console then     require'console'.start()     os.exit() end<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<p>14 \u0438\u044e\u043b\u044f \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u044d\u0442\u043e \u0432 \u0434\u0435\u043b\u0435 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443\u043c\u0435 Rebrain &amp; Tarantool: \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u043c application server \u2014 Tarantool. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e <a href=\"https:\/\/kutt.it\/dho9gY\">\u0441\u0441\u044b\u043b\u043a\u0435<\/a>.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/510440\/\"> https:\/\/habr.com\/ru\/company\/mailru\/blog\/510440\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/510440\/\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/fs\/fk\/f8\/fsfkf8dh0poigt7znuwrcyanlja.jpeg\" alt=\"image\"><\/p>\n<p>  <\/p>\n<p>\u0412 2013 \u044f \u043f\u0440\u0438\u0448\u0435\u043b \u0432 Mail.ru Group, \u0438 \u044f \u0440\u0435\u0448\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439, \u043d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0423\u0441\u043b\u044b\u0448\u0430\u043b, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u2014 Tarantool. \u0423\u0437\u043d\u0430\u043b, \u043a\u0430\u043a \u043e\u043d \u0443\u0441\u0442\u0440\u043e\u0435\u043d, \u0438 \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0432 \u043d\u0435\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u0431\u0440\u043e\u043a\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439. <\/p>\n<p>  <\/p>\n<p>\u042f \u043f\u043e\u0448\u0451\u043b \u043a \u0433\u043b\u0430\u0432\u043d\u043e\u043c\u0443 \u043f\u043e Tarantool \u2014 \u041a\u043e\u0441\u0442\u0435 \u041e\u0441\u0438\u043f\u043e\u0432\u0443 \u2014 \u0438 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 C, \u043a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 Tarantool, \u043d\u043e\u2026 \u041d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0434\u0435\u043d\u044c \u041a\u043e\u0441\u0442\u044f \u0434\u0430\u043b \u043c\u043d\u0435 <a href=\"https:\/\/github.com\/mailru\/tntlua\/commit\/f879dfb6981dc82287b7243074ca6cc9c6038369\">\u0441\u043a\u0440\u0438\u043f\u0442<\/a> \u043d\u0430 250 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b.<\/p>\n<p>  <\/p>\n<p>\u0421 \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u044f \u0432\u043b\u044e\u0431\u0438\u043b\u0441\u044f \u0432 Tarantool. \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u043e\u0432\u0443\u044e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0421\u0423\u0411\u0414 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0448\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, Tarantool \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u043b\u0441\u044f, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043f\u043e\u0434 \u0432\u043b\u0438\u044f\u043d\u0438\u0435\u043c \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0434\u0435\u0438 \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0441\u044c. \u042f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c Tarantool, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0435\u0440\u0441\u0438\u0438 2.2.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-306780","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/306780","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=306780"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/306780\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=306780"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=306780"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=306780"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}