diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml index 42316b6092e19b9c62141187d32ca2ef5f217c81..ce325afa57f02ebb851d4fa0faf866508d5d329e 100644 --- a/doc/user/stored-procedures.xml +++ b/doc/user/stored-procedures.xml @@ -2727,7 +2727,7 @@ for instructions about defining triggers for connect and disconnect events The channel is garbage collected when no one is using it, as with any other Lua object. Object-oriented and functional APIs are equivalent, so <code>channel:put(message)</code> - is the same as <code>box.ipc.channel.put(channel, message)</code>. + is the same as <code>channel:put(channel, message)</code>. </para> <variablelist xml:id="box.ipc"> <para> @@ -2747,11 +2747,11 @@ for instructions about defining triggers for connect and disconnect events </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.put(<replaceable>channel, message[, timeout]</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:put(<replaceable>channel, message[, timeout]</replaceable>)</emphasis></term> <listitem> <para> Send a message using a channel. If the channel is full, - <code>box.ipc.channel.put()</code> + <code>channel:put()</code> blocks until there is a free slot in the channel. </para> <para> @@ -2761,17 +2761,28 @@ for instructions about defining triggers for connect and disconnect events Returns: If <code>timeout</code> is provided, and the channel doesn't become empty for the duration of the timeout, - <code>box.ipc.channel.put()</code> + <code>channel:put()</code> returns false. Otherwise it returns true. </para> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.get(<replaceable>channel[, timeout]</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:close()</emphasis></term> + <listitem> + <simpara> + Close the channel. All waiters in the channel will be + woken up. All following <code>channel:put()</code> + or <code>channel:get()</code> operations will return + an error (nil). + </simpara> + </listitem> + </varlistentry> + <varlistentry> + <term><emphasis role="lua">channel:get(<replaceable>channel[, timeout]</replaceable>)</emphasis></term> <listitem> <para> Fetch a message from a channel. If the channel is empty, - <code>box.ipc.channel.get()</code> + <code>channel:get()</code> blocks until there is a message. </para> <para> @@ -2781,18 +2792,18 @@ for instructions about defining triggers for connect and disconnect events Possible errors: If <code>timeout</code> is provided, and there are no new messages for the duration of the timeout, - <code>box.ipc.channel.get()</code> + <code>channel:get()</code> returns error. </para> </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.broadcast(<replaceable>channel, message, timeout</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:broadcast(<replaceable>channel, message, timeout</replaceable>)</emphasis></term> <listitem> <para> - If the channel is empty, <code>box.ipc.channel.broadcast()</code> is equivalent to - <code>box.ipc.channel.put()</code>. - Otherwise, <code>box.ipc.channel.broadcast()</code> sends the message to all readers of the + If the channel is empty, <code>channel:broadcast()</code> is equivalent to + <code>channel:put()</code>. + Otherwise, <code>channel:broadcast()</code> sends the message to all readers of the channel. </para> <para> @@ -2801,7 +2812,7 @@ for instructions about defining triggers for connect and disconnect events </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.is_empty(<replaceable>channel</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:is_empty(<replaceable>channel</replaceable>)</emphasis></term> <listitem> <para> Check whether the specified channel is empty (has no messages). @@ -2815,7 +2826,7 @@ for instructions about defining triggers for connect and disconnect events </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.is_full(<replaceable>channel</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:is_full(<replaceable>channel</replaceable>)</emphasis></term> <listitem> <para> Check whether the specified channel is full. @@ -2829,11 +2840,11 @@ for instructions about defining triggers for connect and disconnect events </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.has_readers(<replaceable>channel</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:has_readers(<replaceable>channel</replaceable>)</emphasis></term> <listitem> <para> Check whether the specified channel is empty and has readers waiting - for a message (because they have issued <code>box.ipc.channel.get()</code> and then + for a message (because they have issued <code>channel:get()</code> and then blocked). </para> <para> @@ -2845,11 +2856,11 @@ for instructions about defining triggers for connect and disconnect events </listitem> </varlistentry> <varlistentry> - <term><emphasis role="lua">box.ipc.channel.has_writers(<replaceable>channel</replaceable>)</emphasis></term> + <term><emphasis role="lua">channel:has_writers(<replaceable>channel</replaceable>)</emphasis></term> <listitem> <para> Check whether the specified channel is full and has writers waiting - (because they have issued <code>box.ipc.channel.put()</code> and then blocked + (because they have issued <code>channel:put()</code> and then blocked due to lack of room). </para> <para> @@ -2860,6 +2871,16 @@ for instructions about defining triggers for connect and disconnect events </para> </listitem> </varlistentry> + <varlistentry> + <term><emphasis role="lua">channel:is_closed()</emphasis></term> + <listitem> + <simpara> + Return true if the specified channel is already + closed. + Otherwise return false. + </simpara> + </listitem> + </varlistentry> </variablelist> <para> <bridgehead renderas="sect4">Example</bridgehead><programlisting> diff --git a/doc/user/target.db b/doc/user/target.db index cb1b971f7a82a9899ba62e06c308b6e4a5237d91..8eefc54c5319b1effd04c5358cdd2b6ecf9ec13c 100644 --- a/doc/user/target.db +++ b/doc/user/target.db @@ -1,7 +1,7 @@ -<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool User Guide, version 1.6.0-353-gdeb3b39</ttl><xreftext>Tarantool User Guide, version 1.6.0-353-gdeb3b39</xreftext><div element="chapter" href="#preface" number="1" targetptr="preface"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#tarantool-overview" number="" targetptr="tarantool-overview"><ttl>Tarantool: an overview</ttl><xreftext>the section called “Tarantool: an overviewâ€</xreftext></div><div element="section" href="#manual-conventions" number="" targetptr="manual-conventions"><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#reporting-bugs" number="" targetptr="reporting-bugs"><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#getting-started" number="2" targetptr="getting-started"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext><div element="section" href="#getting-started-binary" number="" targetptr="getting-started-binary"><ttl>Downloading and installing a binary package</ttl><xreftext>the section called “Downloading and installing a binary packageâ€</xreftext></div><div element="section" href="#getting-started-source" number="" targetptr="getting-started-source"><ttl>Downloading and building a source package</ttl><xreftext>the section called “Downloading and building a source packageâ€</xreftext></div><div element="section" href="#getting-started-start-stop" number="" targetptr="getting-started-start-stop"><ttl>Starting Tarantool and making your first database</ttl><xreftext>the section called “Starting Tarantool and making your first databaseâ€</xreftext></div></div><div element="chapter" href="#data-and-persistence" number="3" targetptr="data-and-persistence"><ttl>Data model and data persistence</ttl><xreftext>Chapter 3, <i>Data model and data persistence</i></xreftext><div element="section" href="#dynamic-data-model" number="" targetptr="dynamic-data-model"><ttl>Dynamic data model</ttl><xreftext>the section called “Dynamic data modelâ€</xreftext></div><div element="section" href="#data-persistence" number="" targetptr="data-persistence"><ttl>Data persistence</ttl><xreftext>the section called “Data persistenceâ€</xreftext></div></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#data-manipulation" number="" targetptr="data-manipulation"><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext></div><div element="section" href="#administrative-console" number="" targetptr="administrative-console"><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#box.snapshot" number="" targetptr="box.snapshot"><ttl>???TITLE???</ttl><xreftext>box.snapshot()</xreftext></obj><obj element="term" href="#box.cfg.reload" number="" targetptr="box.cfg.reload"><ttl>???TITLE???</ttl><xreftext>box.cfg.reload()</xreftext></obj><obj element="term" href="#box.cfg.show" number="" targetptr="box.cfg.show"><ttl>???TITLE???</ttl><xreftext>box.cfg()</xreftext></obj><obj element="term" href="#box.info" number="" targetptr="box.info"><ttl>???TITLE???</ttl><xreftext>box.info()</xreftext></obj><obj element="term" href="#box.stat.show" number="" targetptr="box.stat.show"><ttl>???TITLE???</ttl><xreftext>box.stat()</xreftext></obj><obj element="term" href="#box.slab.info" number="" targetptr="box.slab.info"><ttl>???TITLE???</ttl><xreftext>box.slab.info()</xreftext></obj><obj element="term" href="#box.coredump" number="" targetptr="box.coredump"><ttl>???TITLE???</ttl><xreftext>box.coredump()</xreftext></obj><obj element="term" href="#box.fiber.info" number="" targetptr="box.fiber.info"><ttl>???TITLE???</ttl><xreftext>box.fiber.info()</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext> +<div element="book" href="#tarantool-user-guide" number="" targetptr="tarantool-user-guide"><ttl>Tarantool User Guide, version 1.6.1-279-ga84cec2</ttl><xreftext>Tarantool User Guide, version 1.6.1-279-ga84cec2</xreftext><div element="chapter" href="#preface" number="1" targetptr="preface"><ttl>Preface</ttl><xreftext>Chapter 1, <i>Preface</i></xreftext><div element="section" href="#tarantool-overview" number="" targetptr="tarantool-overview"><ttl>Tarantool: an overview</ttl><xreftext>the section called “Tarantool: an overviewâ€</xreftext></div><div element="section" href="#manual-conventions" number="" targetptr="manual-conventions"><ttl>Conventions</ttl><xreftext>the section called “Conventionsâ€</xreftext></div><div element="section" href="#reporting-bugs" number="" targetptr="reporting-bugs"><ttl>Reporting bugs</ttl><xreftext>the section called “Reporting bugsâ€</xreftext></div></div><div element="chapter" href="#getting-started" number="2" targetptr="getting-started"><ttl>Getting started</ttl><xreftext>Chapter 2, <i>Getting started</i></xreftext><div element="section" href="#getting-started-binary" number="" targetptr="getting-started-binary"><ttl>Downloading and installing a binary package</ttl><xreftext>the section called “Downloading and installing a binary packageâ€</xreftext></div><div element="section" href="#getting-started-source" number="" targetptr="getting-started-source"><ttl>Downloading and building a source package</ttl><xreftext>the section called “Downloading and building a source packageâ€</xreftext></div><div element="section" href="#getting-started-start-stop" number="" targetptr="getting-started-start-stop"><ttl>Starting Tarantool and making your first database</ttl><xreftext>the section called “Starting Tarantool and making your first databaseâ€</xreftext></div><div element="section" href="#differences-from-older-versions" number="" targetptr="differences-from-older-versions"><ttl>Differences between Tarantool 1.6 and older versions</ttl><xreftext>the section called “Differences between Tarantool 1.6 and older versionsâ€</xreftext></div></div><div element="chapter" href="#data-and-persistence" number="3" targetptr="data-and-persistence"><ttl>Data model and data persistence</ttl><xreftext>Chapter 3, <i>Data model and data persistence</i></xreftext><div element="section" href="#dynamic-data-model" number="" targetptr="dynamic-data-model"><ttl>Dynamic data model</ttl><xreftext>the section called “Dynamic data modelâ€</xreftext></div><div element="section" href="#data-persistence" number="" targetptr="data-persistence"><ttl>Data persistence</ttl><xreftext>the section called “Data persistenceâ€</xreftext></div></div><div element="chapter" href="#language-reference" number="4" targetptr="language-reference"><ttl>Language reference</ttl><xreftext>Chapter 4, <i>Language reference</i></xreftext><div element="section" href="#data-manipulation" number="" targetptr="data-manipulation"><ttl>Data manipulation</ttl><xreftext>the section called “Data manipulationâ€</xreftext></div><div element="section" href="#administrative-console" number="" targetptr="administrative-console"><ttl>Administrative console</ttl><xreftext>the section called “Administrative consoleâ€</xreftext><obj element="term" href="#box.snapshot" number="" targetptr="box.snapshot"><ttl>???TITLE???</ttl><xreftext>box.snapshot()</xreftext></obj><obj element="term" href="#box.cfg.reload" number="" targetptr="box.cfg.reload"><ttl>???TITLE???</ttl><xreftext>box.cfg.reload()</xreftext></obj><obj element="term" href="#box.cfg.show" number="" targetptr="box.cfg.show"><ttl>???TITLE???</ttl><xreftext>box.cfg()</xreftext></obj><obj element="term" href="#box.info" number="" targetptr="box.info"><ttl>???TITLE???</ttl><xreftext>box.info()</xreftext></obj><obj element="term" href="#show-index" number="" targetptr="show-index"><ttl>???TITLE???</ttl><xreftext>SHOW INDEX</xreftext></obj><obj element="term" href="#box.stat.show" number="" targetptr="box.stat.show"><ttl>???TITLE???</ttl><xreftext>box.stat.show()</xreftext></obj><obj element="term" href="#box.slab.info" number="" targetptr="box.slab.info"><ttl>???TITLE???</ttl><xreftext>box.slab.info()</xreftext></obj><obj element="term" href="#box.coredump" number="" targetptr="box.coredump"><ttl>???TITLE???</ttl><xreftext>box.coredump()</xreftext></obj><obj element="term" href="#box.fiber.info" number="" targetptr="box.fiber.info"><ttl>???TITLE???</ttl><xreftext>box.fiber.info()</xreftext></obj><obj element="term" href="#lua-command" number="" targetptr="lua-command"><ttl>???TITLE???</ttl><xreftext> <span class="tntadmin">...</span> - </xreftext></obj></div><div element="section" href="#stored-procedures" number="" targetptr="stored-procedures"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext><obj element="filename" href="#init.lua" number="" targetptr="init.lua"><ttl>???TITLE???</ttl><xreftext>init.lua</xreftext></obj><obj element="term" href="#tonumber64" number="" targetptr="tonumber64"><ttl>???TITLE???</ttl><xreftext>tonumber64</xreftext></obj><div element="section" href="#sp-box" number="" targetptr="sp-box"><ttl>Package <code class="code">box</code></ttl><xreftext>the section called “Package <code class="code">box</code>â€</xreftext><obj element="variablelist" href="#box" number="" targetptr="box"><ttl>???TITLE???</ttl><xreftext>box</xreftext></obj><obj element="emphasis" href="#box.process" number="" targetptr="box.process"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select" number="" targetptr="box.select"><ttl>???TITLE???</ttl><xreftext>box.select</xreftext></obj><obj element="emphasis" href="#box.insert" number="" targetptr="box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_limit" number="" targetptr="box.select_limit"><ttl>???TITLE???</ttl><xreftext>box.select_limit</xreftext></obj><obj element="emphasis" href="#box.replace" number="" targetptr="box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.update" number="" targetptr="box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.delete" number="" targetptr="box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_range" number="" targetptr="box.select_range"><ttl>???TITLE???</ttl><xreftext>box.select_range</xreftext></obj><obj element="emphasis" href="#box.select_reverse_range" number="" targetptr="box.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-tuple" number="" targetptr="sp-box-tuple"><ttl>Package <code class="code">box.tuple</code></ttl><xreftext>the section called “Package <code class="code">box.tuple</code>â€</xreftext><obj element="variablelist" href="#box.tuple" number="" targetptr="box.tuple"><ttl>???TITLE???</ttl><xreftext>box.tuple</xreftext></obj></div><div element="section" href="#sp-box-cjson" number="" targetptr="sp-box-cjson"><ttl>Package <code class="code">box.cjson</code></ttl><xreftext>the section called “Package <code class="code">box.cjson</code>â€</xreftext><obj element="variablelist" href="#box.cjson" number="" targetptr="box.cjson"><ttl>???TITLE???</ttl><xreftext>box.cjson</xreftext></obj></div><div element="section" href="#sp-box-space" number="" targetptr="sp-box-space"><ttl>Package <code class="code">box.space</code></ttl><xreftext>the section called “Package <code class="code">box.space</code>â€</xreftext><obj element="variablelist" href="#box.space" number="" targetptr="box.space"><ttl>???TITLE???</ttl><xreftext>box.space</xreftext></obj><obj element="emphasis" href="#box.space.select_range" number="" targetptr="box.space.select_range"><ttl>???TITLE???</ttl><xreftext>box.space[i].select_range()</xreftext></obj><obj element="emphasis" href="#box.space.select_reverse_range" number="" targetptr="box.space.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.space.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-index" number="" targetptr="sp-box-index"><ttl>Package <code class="code">box.index</code></ttl><xreftext>the section called “Package <code class="code">box.index</code>â€</xreftext><obj element="variablelist" href="#box.index" number="" targetptr="box.index"><ttl>???TITLE???</ttl><xreftext>box.index</xreftext></obj><obj element="emphasis" href="#box.index.iterator" number="" targetptr="box.index.iterator"><ttl>???TITLE???</ttl><xreftext>box.index.iterator(type, ...)</xreftext></obj><obj element="para" href="#iterator-consistency" number="" targetptr="iterator-consistency"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="para" href="#iterator-types" number="" targetptr="iterator-types"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="table" href="#idp25645584" number="4.1"><ttl>Common iterator types</ttl><xreftext>Table 4.1, “Common iterator typesâ€</xreftext></obj><obj element="table" href="#idp25341120" number="4.2"><ttl>TREE iterator types</ttl><xreftext>Table 4.2, “TREE iterator typesâ€</xreftext></obj><obj element="table" href="#idp25358624" number="4.3"><ttl>BITSET iterator types</ttl><xreftext>Table 4.3, “BITSET iterator typesâ€</xreftext></obj></div><div element="section" href="#sp-box-fiber" number="" targetptr="sp-box-fiber"><ttl>Package <code class="code">box.fiber</code></ttl><xreftext>the section called “Package <code class="code">box.fiber</code>â€</xreftext><obj element="variablelist" href="#box.fiber" number="" targetptr="box.fiber"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.fiber.id" number="" targetptr="box.fiber.id"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.self" number="" targetptr="box.fiber.self"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.find" number="" targetptr="box.fiber.find"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.create" number="" targetptr="box.fiber.create"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.resume" number="" targetptr="box.fiber.resume"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.yield" number="" targetptr="box.fiber.yield"><ttl>???TITLE???</ttl><xreftext>box.fiber.yield(...)</xreftext></obj><obj element="emphasis" href="#box.fiber.detach" number="" targetptr="box.fiber.detach"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.wrap" number="" targetptr="box.fiber.wrap"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.sleep" number="" targetptr="box.fiber.sleep"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.status" number="" targetptr="box.fiber.status"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.cancel" number="" targetptr="box.fiber.cancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.testcancel" number="" targetptr="box.fiber.testcancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-session" number="" targetptr="sp-box-session"><ttl>Package <code class="code">box.session</code></ttl><xreftext>the section called “Package <code class="code">box.session</code>â€</xreftext></div><div element="section" href="#sp-box-ipc" number="" targetptr="sp-box-ipc"><ttl>Package <code class="code">box.ipc</code> — inter procedure communication</ttl><xreftext>the section called “Package <code class="code">box.ipc</code> — inter procedure communicationâ€</xreftext><obj element="variablelist" href="#box.ipc" number="" targetptr="box.ipc"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj></div><div element="section" href="#sp-box-socket" number="" targetptr="sp-box-socket"><ttl>Package <code class="code">box.socket</code> — TCP and UDP sockets</ttl><xreftext>the section called “Package <code class="code">box.socket</code> — TCP and UDP socketsâ€</xreftext><obj element="variablelist" href="#box.socket" number="" targetptr="box.socket"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="table" href="#idp25542512" number="4.4"><ttl><code class="code">readline()</code> returns</ttl><xreftext>Table 4.4, “<code class="code">readline()</code> returnsâ€</xreftext></obj></div><div element="section" href="#sp-box-net-box" number="" targetptr="sp-box-net-box"><ttl>Package <code class="code">box.net.box</code> — working with networked Tarantool peers</ttl><xreftext>the section called “Package <code class="code">box.net.box</code> — working with networked Tarantool peersâ€</xreftext><obj element="variablelist" href="#box.net.box" number="" targetptr="box.net.box"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.net.box.new" number="" targetptr="box.net.box.new"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.ping" number="" targetptr="box.net.box.ping"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.close" number="" targetptr="box.net.box.close"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select" number="" targetptr="box.net.box.select"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_limit" number="" targetptr="box.net.box.select_limit"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_range" number="" targetptr="box.net.box.select_range"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.insert" number="" targetptr="box.net.box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.replace" number="" targetptr="box.net.box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.update" number="" targetptr="box.net.box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.delete" number="" targetptr="box.net.box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.call" number="" targetptr="box.net.box.call"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.timeout" number="" targetptr="box.net.box.timeout"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-cfg" number="" targetptr="sp-box-cfg"><ttl>Packages <code class="code">box.cfg</code>, + </xreftext></obj></div><div element="section" href="#stored-procedures" number="" targetptr="stored-procedures"><ttl>Writing stored procedures in Lua</ttl><xreftext>the section called “Writing stored procedures in Luaâ€</xreftext><obj element="filename" href="#init.lua" number="" targetptr="init.lua"><ttl>???TITLE???</ttl><xreftext>init.lua</xreftext></obj><obj element="term" href="#tonumber64" number="" targetptr="tonumber64"><ttl>???TITLE???</ttl><xreftext>tonumber64</xreftext></obj><div element="section" href="#sp-box-library" number="" targetptr="sp-box-library"><ttl>The <code class="code">box</code> library</ttl><xreftext>the section called “The <code class="code">box</code> libraryâ€</xreftext><obj element="table" href="#idp724256" number="4.1"><ttl>Possible types of the values that a function in the box library can return</ttl><xreftext>Table 4.1, “Possible types of the values that a function in the box library can returnâ€</xreftext></obj><obj element="title" href="#function-types" number="" targetptr="function-types"><ttl>Possible types of the values that a function in the box library can return</ttl><xreftext>Table 4.1, “Possible types of the values that a function in the box library can returnâ€</xreftext></obj><obj element="entry" href="#function-type-number" number="" targetptr="function-type-number"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="entry" href="#function-type-string" number="" targetptr="function-type-string"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="entry" href="#function-type-nil" number="" targetptr="function-type-nil"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="entry" href="#function-type-lua-table" number="" targetptr="function-type-lua-table"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="entry" href="#function-type-tuple" number="" targetptr="function-type-tuple"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box" number="" targetptr="sp-box"><ttl>Package <code class="code">box</code></ttl><xreftext>the section called “Package <code class="code">box</code>â€</xreftext><obj element="variablelist" href="#box" number="" targetptr="box"><ttl>???TITLE???</ttl><xreftext>box</xreftext></obj><obj element="emphasis" href="#box.process" number="" targetptr="box.process"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select" number="" targetptr="box.select"><ttl>???TITLE???</ttl><xreftext>box.select</xreftext></obj><obj element="emphasis" href="#box.insert" number="" targetptr="box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_limit" number="" targetptr="box.select_limit"><ttl>???TITLE???</ttl><xreftext>box.select_limit</xreftext></obj><obj element="emphasis" href="#box.replace" number="" targetptr="box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.update" number="" targetptr="box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.delete" number="" targetptr="box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.select_range" number="" targetptr="box.select_range"><ttl>???TITLE???</ttl><xreftext>box.select_range</xreftext></obj><obj element="emphasis" href="#box.select_reverse_range" number="" targetptr="box.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-tuple" number="" targetptr="sp-box-tuple"><ttl>Package <code class="code">box.tuple</code></ttl><xreftext>the section called “Package <code class="code">box.tuple</code>â€</xreftext><obj element="variablelist" href="#box.tuple" number="" targetptr="box.tuple"><ttl>???TITLE???</ttl><xreftext>box.tuple</xreftext></obj></div><div element="section" href="#sp-box-cjson" number="" targetptr="sp-box-cjson"><ttl>Package <code class="code">box.cjson</code></ttl><xreftext>the section called “Package <code class="code">box.cjson</code>â€</xreftext><obj element="variablelist" href="#box.cjson" number="" targetptr="box.cjson"><ttl>???TITLE???</ttl><xreftext>box.cjson</xreftext></obj></div><div element="section" href="#sp-box-space" number="" targetptr="sp-box-space"><ttl>Package <code class="code">box.space</code></ttl><xreftext>the section called “Package <code class="code">box.space</code>â€</xreftext><obj element="variablelist" href="#box.space" number="" targetptr="box.space"><ttl>???TITLE???</ttl><xreftext>box.space</xreftext></obj><obj element="emphasis" href="#box.space.select_range" number="" targetptr="box.space.select_range"><ttl>???TITLE???</ttl><xreftext>box.space[i].select_range()</xreftext></obj><obj element="emphasis" href="#box.space.select_reverse_range" number="" targetptr="box.space.select_reverse_range"><ttl>???TITLE???</ttl><xreftext>box.space.select_reverse_range</xreftext></obj></div><div element="section" href="#sp-box-index" number="" targetptr="sp-box-index"><ttl>Package <code class="code">box.index</code></ttl><xreftext>the section called “Package <code class="code">box.index</code>â€</xreftext><obj element="variablelist" href="#box.index" number="" targetptr="box.index"><ttl>???TITLE???</ttl><xreftext>box.index</xreftext></obj><obj element="emphasis" href="#box.index.iterator" number="" targetptr="box.index.iterator"><ttl>???TITLE???</ttl><xreftext>box.index.iterator(type, ...)</xreftext></obj><obj element="para" href="#iterator-consistency" number="" targetptr="iterator-consistency"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="para" href="#iterator-types" number="" targetptr="iterator-types"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="table" href="#idp1114672" number="4.2"><ttl>Common iterator types</ttl><xreftext>Table 4.2, “Common iterator typesâ€</xreftext></obj><obj element="table" href="#idp983120" number="4.3"><ttl>TREE iterator types</ttl><xreftext>Table 4.3, “TREE iterator typesâ€</xreftext></obj><obj element="table" href="#idp1000912" number="4.4"><ttl>BITSET iterator types</ttl><xreftext>Table 4.4, “BITSET iterator typesâ€</xreftext></obj></div><div element="section" href="#sp-box-fiber" number="" targetptr="sp-box-fiber"><ttl>Package <code class="code">box.fiber</code></ttl><xreftext>the section called “Package <code class="code">box.fiber</code>â€</xreftext><obj element="variablelist" href="#box.fiber" number="" targetptr="box.fiber"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.fiber.id" number="" targetptr="box.fiber.id"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.self" number="" targetptr="box.fiber.self"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.find" number="" targetptr="box.fiber.find"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.create" number="" targetptr="box.fiber.create"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.resume" number="" targetptr="box.fiber.resume"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.yield" number="" targetptr="box.fiber.yield"><ttl>???TITLE???</ttl><xreftext>box.fiber.yield</xreftext></obj><obj element="emphasis" href="#box.fiber.detach" number="" targetptr="box.fiber.detach"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.wrap" number="" targetptr="box.fiber.wrap"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.sleep" number="" targetptr="box.fiber.sleep"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.status" number="" targetptr="box.fiber.status"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.cancel" number="" targetptr="box.fiber.cancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.fiber.testcancel" number="" targetptr="box.fiber.testcancel"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-session" number="" targetptr="sp-box-session"><ttl>Package <code class="code">box.session</code></ttl><xreftext>the section called “Package <code class="code">box.session</code>â€</xreftext></div><div element="section" href="#sp-box-ipc" number="" targetptr="sp-box-ipc"><ttl>Package <code class="code">box.ipc</code> — inter procedure communication</ttl><xreftext>the section called “Package <code class="code">box.ipc</code> — inter procedure communicationâ€</xreftext><obj element="variablelist" href="#box.ipc" number="" targetptr="box.ipc"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj></div><div element="section" href="#sp-box-socket" number="" targetptr="sp-box-socket"><ttl>Package <code class="code">box.socket</code> — TCP and UDP sockets</ttl><xreftext>the section called “Package <code class="code">box.socket</code> — TCP and UDP socketsâ€</xreftext><obj element="variablelist" href="#box.socket" number="" targetptr="box.socket"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="table" href="#idp622752" number="4.5"><ttl><code class="code">readline()</code> returns</ttl><xreftext>Table 4.5, “<code class="code">readline()</code> returnsâ€</xreftext></obj></div><div element="section" href="#sp-box-net-box" number="" targetptr="sp-box-net-box"><ttl>Package <code class="code">box.net.box</code> — working with networked Tarantool peers</ttl><xreftext>the section called “Package <code class="code">box.net.box</code> — working with networked Tarantool peersâ€</xreftext><obj element="variablelist" href="#box.net.box" number="" targetptr="box.net.box"><ttl>???TITLE???</ttl><xreftext>???TITLE???</xreftext></obj><obj element="emphasis" href="#box.net.box.new" number="" targetptr="box.net.box.new"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.ping" number="" targetptr="box.net.box.ping"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.close" number="" targetptr="box.net.box.close"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select" number="" targetptr="box.net.box.select"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_limit" number="" targetptr="box.net.box.select_limit"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.select_range" number="" targetptr="box.net.box.select_range"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.insert" number="" targetptr="box.net.box.insert"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.replace" number="" targetptr="box.net.box.replace"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.update" number="" targetptr="box.net.box.update"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.delete" number="" targetptr="box.net.box.delete"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.call" number="" targetptr="box.net.box.call"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="emphasis" href="#box.net.box.timeout" number="" targetptr="box.net.box.timeout"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-box-cfg" number="" targetptr="sp-box-cfg"><ttl>Packages <code class="code">box.cfg</code>, <code class="code">box.info</code>, <code class="code">box.slab</code> and <code class="code">box.stat</code>: server introspection</ttl><xreftext>the section called “Packages <code class="code">box.cfg</code>, <code class="code">box.info</code>, <code class="code">box.slab</code> and - <code class="code">box.stat</code>: server introspectionâ€</xreftext><obj element="code" href="#box.cfg" number="" targetptr="box.cfg"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="code" href="#box.stat" number="" targetptr="box.stat"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-limitations" number="" targetptr="sp-limitations"><ttl>Limitations of stored procedures</ttl><xreftext>the section called “Limitations of stored proceduresâ€</xreftext></div></div><div element="section" href="#triggers" number="" targetptr="triggers"><ttl>Defining triggers in Lua</ttl><xreftext>the section called “Defining triggers in Luaâ€</xreftext><div element="section" href="#sp-box-session-triggers" number="" targetptr="sp-box-session-triggers"><ttl>Triggers on connect and disconnect</ttl><xreftext>session triggers</xreftext></div></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#replication-architecture" number="" targetptr="replication-architecture"><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#setting-up-the-master" number="" targetptr="setting-up-the-master"><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#settin-up-a-replica" number="" targetptr="settin-up-a-replica"><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#recovering-from-a-degraded-state" number="" targetptr="recovering-from-a-degraded-state"><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#server-administration" number="6" targetptr="server-administration"><ttl>Server administration</ttl><xreftext>Chapter 6, <i>Server administration</i></xreftext><div element="section" href="#signal-handling" number="" targetptr="signal-handling"><ttl>Server signal handling</ttl><xreftext>the section called “Server signal handlingâ€</xreftext></div><div element="section" href="#tarantar" number="" targetptr="tarantar"><ttl>Utility <code class="code">tarantar</code></ttl><xreftext>the section called “Utility <code class="code">tarantar</code>â€</xreftext></div><div element="section" href="#os-install-notes" number="" targetptr="os-install-notes"><ttl>System-specific administration notes</ttl><xreftext>the section called “System-specific administration notesâ€</xreftext><div element="section" href="#Debian" number="" targetptr="Debian"><ttl>Debian GNU/Linux and Ubuntu</ttl><xreftext>the section called “Debian GNU/Linux and Ubuntuâ€</xreftext></div><div element="section" href="#rpm-based-distros" number="" targetptr="rpm-based-distros"><ttl>Fedora, RHEL, CentOS</ttl><xreftext>the section called “Fedora, RHEL, CentOSâ€</xreftext></div><div element="section" href="#FreeBSD" number="" targetptr="FreeBSD"><ttl>FreeBSD</ttl><xreftext>the section called “FreeBSDâ€</xreftext></div><div element="section" href="#mac-os-x" number="" targetptr="mac-os-x"><ttl>Mac OS X</ttl><xreftext>the section called “Mac OS Xâ€</xreftext></div></div></div><div element="chapter" href="#configuration-reference" number="7" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 7, <i>Configuration reference</i></xreftext><div element="section" href="#command-line-options" number="" targetptr="command-line-options"><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj></div><div element="section" href="#option-file" number="" targetptr="option-file"><ttl>The option file</ttl><xreftext>option file</xreftext><obj element="table" href="#idp26182784" number="7.1"><ttl>Basic parameters</ttl><xreftext>Table 7.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#work_dir" number="" targetptr="work_dir"><ttl>???TITLE???</ttl><xreftext>work_dir</xreftext></obj><obj element="entry" href="#script_dir" number="" targetptr="script_dir"><ttl>???TITLE???</ttl><xreftext>script_dir</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#bind_ipaddr" number="" targetptr="bind_ipaddr"><ttl>???TITLE???</ttl><xreftext>bind_ipaddr</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp26241360" number="7.2"><ttl>Configuring the storage</ttl><xreftext>Table 7.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The option fileâ€</xreftext></obj><obj element="table" href="#idp26277088" number="7.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 7.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="entry" href="#rows_per_wal" number="" targetptr="rows_per_wal"><ttl>???TITLE???</ttl><xreftext>rows_per_wal</xreftext></obj><obj element="entry" href="#wal_mode" number="" targetptr="wal_mode"><ttl>???TITLE???</ttl><xreftext>wal_mode</xreftext></obj><obj element="table" href="#idp26312272" number="7.4"><ttl>Replication</ttl><xreftext>Table 7.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp26331776" number="7.5"><ttl>Networking</ttl><xreftext>Table 7.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp26351072" number="7.6"><ttl>Logging</ttl><xreftext>Table 7.6, “Loggingâ€</xreftext></obj></div></div><div element="chapter" href="#connectors" number="8" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 8, <i>Connectors</i></xreftext><div element="section" href="#connector-packet-example" number="" targetptr="connector-packet-example"><ttl>Packet example</ttl><xreftext>the section called “Packet exampleâ€</xreftext></div><div element="section" href="#connector-c" number="" targetptr="connector-c"><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#connector-node.js" number="" targetptr="connector-node.js"><ttl>node.js</ttl><xreftext>the section called “node.jsâ€</xreftext></div><div element="section" href="#connector-perl" number="" targetptr="connector-perl"><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#connector-php" number="" targetptr="connector-php"><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#connector-python" number="" targetptr="connector-python"><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#connector-ruby" number="" targetptr="connector-ruby"><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_KEY_PART_COUNT" number="" targetptr="ER_KEY_PART_COUNT"><ttl>???TITLE???</ttl><xreftext>ER_KEY_PART_COUNT</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj><obj element="term" href="#ER_PROC_LUA" number="" targetptr="ER_PROC_LUA"><ttl>???TITLE???</ttl><xreftext>ER_PROC_LUA</xreftext></obj><obj element="term" href="#ER_FIBER_STACK" number="" targetptr="ER_FIBER_STACK"><ttl>???TITLE???</ttl><xreftext>ER_FIBER_STACK</xreftext></obj><obj element="term" href="#ER_UPDATE_FIELD" number="" targetptr="ER_UPDATE_FIELD"><ttl>???TITLE???</ttl><xreftext>ER_UPDATE_FIELD</xreftext></obj></div><div element="appendix" href="#limitations" number="C" targetptr="limitations"><ttl>Limitations</ttl><xreftext>Appendix C, <i>Limitations</i></xreftext><obj element="term" href="#limitations-index-field-count" number="" targetptr="limitations-index-field-count"><ttl>???TITLE???</ttl><xreftext>limitations-index-field-count</xreftext></obj><obj element="term" href="#limitations-index-count" number="" targetptr="limitations-index-count"><ttl>???TITLE???</ttl><xreftext>limitations-index-count</xreftext></obj><obj element="term" href="#limitations-tuple-field-count" number="" targetptr="limitations-tuple-field-count"><ttl>???TITLE???</ttl><xreftext>limitations-tuple-field-count</xreftext></obj><obj element="term" href="#limitations-space-count" number="" targetptr="limitations-space-count"><ttl>???TITLE???</ttl><xreftext>limitations-space-count</xreftext></obj><obj element="term" href="#limitations-connections-count" number="" targetptr="limitations-connections-count"><ttl>???TITLE???</ttl><xreftext>limitations-connections-count</xreftext></obj><obj element="term" href="#limitations-slab-alloc-arena-size" number="" targetptr="limitations-slab-alloc-arena-size"><ttl>???TITLE???</ttl><xreftext>limitations-slab-alloc-arena-size</xreftext></obj><obj element="term" href="#limitations-update-count" number="" targetptr="limitations-update-count"><ttl>???TITLE???</ttl><xreftext>limitations-updae-count</xreftext></obj></div></div> + <code class="code">box.stat</code>: server introspectionâ€</xreftext><obj element="code" href="#box.cfg" number="" targetptr="box.cfg"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj><obj element="code" href="#box.stat" number="" targetptr="box.stat"><ttl>???TITLE???</ttl><xreftext>???</xreftext></obj></div><div element="section" href="#sp-limitations" number="" targetptr="sp-limitations"><ttl>Limitations of stored procedures</ttl><xreftext>the section called “Limitations of stored proceduresâ€</xreftext></div></div><div element="section" href="#triggers" number="" targetptr="triggers"><ttl>Defining triggers in Lua</ttl><xreftext>the section called “Defining triggers in Luaâ€</xreftext><div element="section" href="#sp-box-session-triggers" number="" targetptr="sp-box-session-triggers"><ttl>Triggers on connect and disconnect</ttl><xreftext>session triggers</xreftext></div></div></div><div element="chapter" href="#replication" number="5" targetptr="replication"><ttl>Replication</ttl><xreftext>Chapter 5, <i>Replication</i></xreftext><div element="section" href="#replication-architecture" number="" targetptr="replication-architecture"><ttl>Replication architecture</ttl><xreftext>the section called “Replication architectureâ€</xreftext></div><div element="section" href="#setting-up-the-master" number="" targetptr="setting-up-the-master"><ttl>Setting up the master</ttl><xreftext>the section called “Setting up the masterâ€</xreftext></div><div element="section" href="#settin-up-a-replica" number="" targetptr="settin-up-a-replica"><ttl>Setting up a replica</ttl><xreftext>the section called “Setting up a replicaâ€</xreftext></div><div element="section" href="#recovering-from-a-degraded-state" number="" targetptr="recovering-from-a-degraded-state"><ttl>Recovering from a degraded state</ttl><xreftext>the section called “Recovering from a degraded stateâ€</xreftext></div></div><div element="chapter" href="#server-administration" number="6" targetptr="server-administration"><ttl>Server administration</ttl><xreftext>Chapter 6, <i>Server administration</i></xreftext><div element="section" href="#signal-handling" number="" targetptr="signal-handling"><ttl>Server signal handling</ttl><xreftext>the section called “Server signal handlingâ€</xreftext></div><div element="section" href="#utility-tarantool" number="" targetptr="utility-tarantool"><ttl>Utility <code class="code">tarantool</code> — the main client</ttl><xreftext>the section called “Utility <code class="code">tarantool</code> — the main clientâ€</xreftext><obj element="term" href="#utility-tarantool-admin-port" number="" targetptr="utility-tarantool-admin-port"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-admin-port</xreftext></obj><obj element="term" href="#utility-tarantool-bin" number="" targetptr="utility-tarantool-bin"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-bin</xreftext></obj><obj element="term" href="#utility-tarantool-cat" number="" targetptr="utility-tarantool-cat"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-cat</xreftext></obj><obj element="term" href="#utility-tarantool-delim" number="" targetptr="utility-tarantool-delim"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-delim</xreftext></obj><obj element="term" href="#utility-tarantool-format" number="" targetptr="utility-tarantool-format"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-format</xreftext></obj><obj element="term" href="#utility-tarantool-from" number="" targetptr="utility-tarantool-from"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-from</xreftext></obj><obj element="term" href="#utility-tarantool-header" number="" targetptr="utility-tarantool-header"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-header</xreftext></obj><obj element="term" href="#utility-tarantool-help" number="" targetptr="utility-tarantool-help"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-help</xreftext></obj><obj element="term" href="#utility-tarantool-host" number="" targetptr="utility-tarantool-host"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-host</xreftext></obj><obj element="term" href="#utility-tarantool-play" number="" targetptr="utility-tarantool-play"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-play</xreftext></obj><obj element="term" href="#utility-tarantool-port" number="" targetptr="utility-tarantool-port"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-port</xreftext></obj><obj element="term" href="#utility-tarantool-rpl" number="" targetptr="utility-tarantool-rpl"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-rpl</xreftext></obj><obj element="term" href="#utility-tarantool-space" number="" targetptr="utility-tarantool-space"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-space</xreftext></obj><obj element="term" href="#utility-tarantool-to" number="" targetptr="utility-tarantool-to"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-to</xreftext></obj><obj element="term" href="#utility-tarantool-version" number="" targetptr="utility-tarantool-version"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-version</xreftext></obj><obj element="term" href="#utility-tarantool-call" number="" targetptr="utility-tarantool-call"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-call</xreftext></obj><obj element="term" href="#utility-tarantool-delete" number="" targetptr="utility-tarantool-delete"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-delete</xreftext></obj><obj element="term" href="#utility-tarantool-exit" number="" targetptr="utility-tarantool-exit"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-exit</xreftext></obj><obj element="term" href="#utility-tarantool-help2" number="" targetptr="utility-tarantool-help2"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-help2</xreftext></obj><obj element="term" href="#utility-tarantool-insert" number="" targetptr="utility-tarantool-insert"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-insert</xreftext></obj><obj element="term" href="#utility-tarantool-loadfile" number="" targetptr="utility-tarantool-loadfile"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-loadfile</xreftext></obj><obj element="term" href="#utility-tarantool-lua" number="" targetptr="utility-tarantool-lua"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-lua</xreftext></obj><obj element="term" href="#utility-tarantool-ping" number="" targetptr="utility-tarantool-ping"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-ping</xreftext></obj><obj element="term" href="#utility-tarantool-quit" number="" targetptr="utility-tarantool-quit"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-quit</xreftext></obj><obj element="term" href="#utility-tarantool-reload" number="" targetptr="utility-tarantool-reload"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-reload</xreftext></obj><obj element="term" href="#utility-tarantool-replace" number="" targetptr="utility-tarantool-replace"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-replace</xreftext></obj><obj element="term" href="#utility-tarantool-save" number="" targetptr="utility-tarantool-save"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-save</xreftext></obj><obj element="term" href="#utility-tarantool-select" number="" targetptr="utility-tarantool-select"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-select</xreftext></obj><obj element="term" href="#utility-tarantool-set" number="" targetptr="utility-tarantool-set"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-set</xreftext></obj><obj element="term" href="#utility-tarantool-setopt" number="" targetptr="utility-tarantool-setopt"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-setopt</xreftext></obj><obj element="term" href="#utility-tarantool-show" number="" targetptr="utility-tarantool-show"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-show</xreftext></obj><obj element="term" href="#utility-tarantool-update" number="" targetptr="utility-tarantool-update"><ttl>???TITLE???</ttl><xreftext>utility-tarantool-update</xreftext></obj></div><div element="section" href="#tarantar" number="" targetptr="tarantar"><ttl>Utility <code class="code">tarantar</code></ttl><xreftext>the section called “Utility <code class="code">tarantar</code>â€</xreftext></div><div element="section" href="#tarancheck" number="" targetptr="tarancheck"><ttl>Utility <code class="code">tarancheck</code></ttl><xreftext>the section called “Utility <code class="code">tarancheck</code>â€</xreftext></div><div element="section" href="#tarantool_deploy" number="" targetptr="tarantool_deploy"><ttl>Utility <code class="code">tarantool_deploy</code></ttl><xreftext>the section called “Utility <code class="code">tarantool_deploy</code>â€</xreftext></div><div element="section" href="#os-install-notes" number="" targetptr="os-install-notes"><ttl>System-specific administration notes</ttl><xreftext>the section called “System-specific administration notesâ€</xreftext><div element="section" href="#Debian" number="" targetptr="Debian"><ttl>Debian GNU/Linux and Ubuntu</ttl><xreftext>the section called “Debian GNU/Linux and Ubuntuâ€</xreftext></div><div element="section" href="#rpm-based-distros" number="" targetptr="rpm-based-distros"><ttl>Fedora, RHEL, CentOS</ttl><xreftext>the section called “Fedora, RHEL, CentOSâ€</xreftext></div><div element="section" href="#FreeBSD" number="" targetptr="FreeBSD"><ttl>FreeBSD</ttl><xreftext>the section called “FreeBSDâ€</xreftext></div><div element="section" href="#mac-os-x" number="" targetptr="mac-os-x"><ttl>Mac OS X</ttl><xreftext>the section called “Mac OS Xâ€</xreftext></div></div></div><div element="chapter" href="#configuration-reference" number="7" targetptr="configuration-reference"><ttl>Configuration reference</ttl><xreftext>Chapter 7, <i>Configuration reference</i></xreftext><div element="section" href="#command-line-options" number="" targetptr="command-line-options"><ttl>Command line options</ttl><xreftext>the section called “Command line optionsâ€</xreftext><obj element="listitem" href="#help-option" number="" targetptr="help-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#version-option" number="" targetptr="version-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="listitem" href="#config-option" number="" targetptr="config-option"><ttl>???TITLE???</ttl><xreftext/></obj><obj element="option" href="#init-storage-option" number="" targetptr="init-storage-option"><ttl>???TITLE???</ttl><xreftext>--init-storage</xreftext></obj></div><div element="section" href="#configuration-file" number="" targetptr="configuration-file"><ttl>The configuration file</ttl><xreftext>configuration file</xreftext><obj element="table" href="#idp2098320" number="7.1"><ttl>Basic parameters</ttl><xreftext>Table 7.1, “Basic parametersâ€</xreftext></obj><obj element="entry" href="#work_dir" number="" targetptr="work_dir"><ttl>???TITLE???</ttl><xreftext>work_dir</xreftext></obj><obj element="entry" href="#script_dir" number="" targetptr="script_dir"><ttl>???TITLE???</ttl><xreftext>script_dir</xreftext></obj><obj element="entry" href="#wal_dir" number="" targetptr="wal_dir"><ttl>???TITLE???</ttl><xreftext>wal_dir</xreftext></obj><obj element="entry" href="#snap_dir" number="" targetptr="snap_dir"><ttl>???TITLE???</ttl><xreftext>snap_dir</xreftext></obj><obj element="entry" href="#bind_ipaddr" number="" targetptr="bind_ipaddr"><ttl>???TITLE???</ttl><xreftext>bind_ipaddr</xreftext></obj><obj element="entry" href="#primary_port" number="" targetptr="primary_port"><ttl>???TITLE???</ttl><xreftext>primary_port</xreftext></obj><obj element="entry" href="#secondary_port" number="" targetptr="secondary_port"><ttl>???TITLE???</ttl><xreftext>secondary_port</xreftext></obj><obj element="entry" href="#admin_port" number="" targetptr="admin_port"><ttl>???TITLE???</ttl><xreftext>admin_port</xreftext></obj><obj element="entry" href="#custom_proc_title" number="" targetptr="custom_proc_title"><ttl>???TITLE???</ttl><xreftext>custom_proc_title</xreftext></obj><obj element="table" href="#idp2157072" number="7.2"><ttl>Configuring the storage</ttl><xreftext>Table 7.2, “Configuring the storageâ€</xreftext></obj><obj element="anchor" href="#slab_alloc_arena" number="" targetptr="slab_alloc_arena"><ttl>???TITLE???</ttl><xreftext>slab_alloc_arena</xreftext></obj><obj element="para" href="#space" number="" targetptr="space"><ttl>???TITLE???</ttl><xreftext>the section called “The configuration fileâ€</xreftext></obj><obj element="table" href="#idp2193104" number="7.3"><ttl>Binary logging and snapshots</ttl><xreftext>Table 7.3, “Binary logging and snapshotsâ€</xreftext></obj><obj element="entry" href="#rows_per_wal" number="" targetptr="rows_per_wal"><ttl>???TITLE???</ttl><xreftext>rows_per_wal</xreftext></obj><obj element="entry" href="#wal_mode" number="" targetptr="wal_mode"><ttl>???TITLE???</ttl><xreftext>wal_mode</xreftext></obj><obj element="table" href="#idp2228480" number="7.4"><ttl>Replication</ttl><xreftext>Table 7.4, “Replicationâ€</xreftext></obj><obj element="entry" href="#replication_port" number="" targetptr="replication_port"><ttl>???TITLE???</ttl><xreftext>replication_port</xreftext></obj><obj element="entry" href="#replication_source" number="" targetptr="replication_source"><ttl>???TITLE???</ttl><xreftext>replication_source</xreftext></obj><obj element="table" href="#idp2247984" number="7.5"><ttl>Networking</ttl><xreftext>Table 7.5, “Networkingâ€</xreftext></obj><obj element="table" href="#idp2264176" number="7.6"><ttl>Logging</ttl><xreftext>Table 7.6, “Loggingâ€</xreftext></obj><obj element="table" href="#idp2289088" number="7.7"><ttl>Hot Standby</ttl><xreftext>Table 7.7, “Hot Standbyâ€</xreftext></obj><obj element="anchor" href="#local_hot_standby" number="" targetptr="local_hot_standby"><ttl>???TITLE???</ttl><xreftext>local_hot_standby</xreftext></obj></div></div><div element="chapter" href="#connectors" number="8" targetptr="connectors"><ttl>Connectors</ttl><xreftext>Chapter 8, <i>Connectors</i></xreftext><div element="section" href="#connector-packet-example" number="" targetptr="connector-packet-example"><ttl>Packet example</ttl><xreftext>the section called “Packet exampleâ€</xreftext></div><div element="section" href="#connector-c" number="" targetptr="connector-c"><ttl>C</ttl><xreftext>the section called “Câ€</xreftext></div><div element="section" href="#connector-erlang" number="" targetptr="connector-erlang"><ttl>Erlang</ttl><xreftext>the section called “Erlangâ€</xreftext></div><div element="section" href="#connector-java" number="" targetptr="connector-java"><ttl>Java</ttl><xreftext>the section called “Javaâ€</xreftext></div><div element="section" href="#connector-node.js" number="" targetptr="connector-node.js"><ttl>node.js</ttl><xreftext>the section called “node.jsâ€</xreftext></div><div element="section" href="#connector-perl" number="" targetptr="connector-perl"><ttl>Perl</ttl><xreftext>the section called “Perlâ€</xreftext></div><div element="section" href="#connector-php" number="" targetptr="connector-php"><ttl>PHP</ttl><xreftext>the section called “PHPâ€</xreftext></div><div element="section" href="#connector-python" number="" targetptr="connector-python"><ttl>Python</ttl><xreftext>the section called “Pythonâ€</xreftext></div><div element="section" href="#connector-ruby" number="" targetptr="connector-ruby"><ttl>Ruby</ttl><xreftext>the section called “Rubyâ€</xreftext></div></div><div element="appendix" href="#proctitle" number="A" targetptr="proctitle"><ttl>Server process titles</ttl><xreftext>Appendix A, <i>Server process titles</i></xreftext></div><div element="appendix" href="#errcode" number="B" targetptr="errcode"><ttl>List of error codes</ttl><xreftext>Appendix B, <i>List of error codes</i></xreftext><obj element="term" href="#ER_NONMASTER" number="" targetptr="ER_NONMASTER"><ttl>???TITLE???</ttl><xreftext>ER_NONMASTER</xreftext></obj><obj element="term" href="#ER_ILLEGAL_PARAMS" number="" targetptr="ER_ILLEGAL_PARAMS"><ttl>???TITLE???</ttl><xreftext>ER_ILLEGAL_PARAMS</xreftext></obj><obj element="term" href="#ER_MEMORY_ISSUE" number="" targetptr="ER_MEMORY_ISSUE"><ttl>???TITLE???</ttl><xreftext>ER_MEMORY_ISSUE</xreftext></obj><obj element="term" href="#ER_WAL_IO" number="" targetptr="ER_WAL_IO"><ttl>???TITLE???</ttl><xreftext>ER_WAL_IO</xreftext></obj><obj element="term" href="#ER_KEY_PART_COUNT" number="" targetptr="ER_KEY_PART_COUNT"><ttl>???TITLE???</ttl><xreftext>ER_KEY_PART_COUNT</xreftext></obj><obj element="term" href="#ER_NO_SUCH_SPACE" number="" targetptr="ER_NO_SUCH_SPACE"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_SPACE</xreftext></obj><obj element="term" href="#ER_NO_SUCH_INDEX" number="" targetptr="ER_NO_SUCH_INDEX"><ttl>???TITLE???</ttl><xreftext>ER_NO_SUCH_INDEX</xreftext></obj><obj element="term" href="#ER_PROC_LUA" number="" targetptr="ER_PROC_LUA"><ttl>???TITLE???</ttl><xreftext>ER_PROC_LUA</xreftext></obj><obj element="term" href="#ER_FIBER_STACK" number="" targetptr="ER_FIBER_STACK"><ttl>???TITLE???</ttl><xreftext>ER_FIBER_STACK</xreftext></obj><obj element="term" href="#ER_UPDATE_FIELD" number="" targetptr="ER_UPDATE_FIELD"><ttl>???TITLE???</ttl><xreftext>ER_UPDATE_FIELD</xreftext></obj></div><div element="appendix" href="#limitations" number="C" targetptr="limitations"><ttl>Limitations</ttl><xreftext>Appendix C, <i>Limitations</i></xreftext><obj element="term" href="#limitations-index-field-count" number="" targetptr="limitations-index-field-count"><ttl>???TITLE???</ttl><xreftext>limitations-index-field-count</xreftext></obj><obj element="term" href="#limitations-index-count" number="" targetptr="limitations-index-count"><ttl>???TITLE???</ttl><xreftext>limitations-index-count</xreftext></obj><obj element="term" href="#limitations-tuple-field-count" number="" targetptr="limitations-tuple-field-count"><ttl>???TITLE???</ttl><xreftext>limitations-tuple-field-count</xreftext></obj><obj element="term" href="#limitations-space-count" number="" targetptr="limitations-space-count"><ttl>???TITLE???</ttl><xreftext>limitations-space-count</xreftext></obj><obj element="term" href="#limitations-connections-count" number="" targetptr="limitations-connections-count"><ttl>???TITLE???</ttl><xreftext>limitations-connections-count</xreftext></obj><obj element="term" href="#limitations-slab-alloc-arena-size" number="" targetptr="limitations-slab-alloc-arena-size"><ttl>???TITLE???</ttl><xreftext>limitations-slab-alloc-arena-size</xreftext></obj><obj element="term" href="#limitations-update-count" number="" targetptr="limitations-update-count"><ttl>???TITLE???</ttl><xreftext>limitations-updae-count</xreftext></obj></div><div element="appendix" href="#lua-tutorial" number="D" targetptr="lua-tutorial"><ttl>Lua tutorial</ttl><xreftext>Appendix D, <i>Lua tutorial</i></xreftext><div element="section" href="#lua-tutorial-insert" number="" targetptr="lua-tutorial-insert"><ttl>Insert one million tuples with a Lua stored procedure</ttl><xreftext>the section called “Insert one million tuples with a Lua stored procedureâ€</xreftext></div><div element="section" href="#lua-tutorial-sum" number="" targetptr="lua-tutorial-sum"><ttl>Sum a JSON field for all tuples</ttl><xreftext>the section called “Sum a JSON field for all tuplesâ€</xreftext></div></div><div element="appendix" href="#plugins" number="E" targetptr="plugins"><ttl>Plugins</ttl><xreftext>Appendix E, <i>Plugins</i></xreftext><obj element="para" href="#plugin-sql-dbms-plugins" number="" targetptr="plugin-sql-dbms-plugins"><ttl>???TITLE???</ttl><xreftext>Appendix E, <i>Plugins</i></xreftext></obj><obj element="para" href="#plugin-mysql-example" number="" targetptr="plugin-mysql-example"><ttl>???TITLE???</ttl><xreftext>Appendix E, <i>Plugins</i></xreftext></obj><obj element="para" href="#plugin-postgresql-example" number="" targetptr="plugin-postgresql-example"><ttl>???TITLE???</ttl><xreftext>Appendix E, <i>Plugins</i></xreftext></obj></div></div> diff --git a/src/ipc.cc b/src/ipc.cc index 9e44f86ebd5d8b5a166e39a150bfffce82045d8b..c86df812b53469d7d0fc1c5ae153a556b8062940 100644 --- a/src/ipc.cc +++ b/src/ipc.cc @@ -32,7 +32,10 @@ #include "salad/rlist.h" struct ipc_channel { - struct rlist readers, writers, bcast; + struct rlist readers, writers; + struct fiber *bcast; /* broadcast waiter */ + struct fiber *close; /* close waiter */ + bool closed; /* channel is closed */ unsigned size; unsigned beg; unsigned count; @@ -83,7 +86,9 @@ static void ipc_channel_create(struct ipc_channel *ch) { ch->beg = ch->count = 0; - rlist_create(&ch->bcast); + ch->closed = false; + ch->close = NULL; + ch->bcast = NULL; rlist_create(&ch->readers); rlist_create(&ch->writers); } @@ -106,12 +111,15 @@ ipc_channel_destroy(struct ipc_channel *ch) void * ipc_channel_get_timeout(struct ipc_channel *ch, ev_tstamp timeout) { + if (ch->closed) + return NULL; + struct fiber *f; bool first_try = true; ev_tstamp started = ev_now(loop()); + void *res; /* channel is empty */ while (ch->count == 0) { - /* try to be in FIFO order */ if (first_try) { rlist_add_tail_entry(&ch->readers, fiber(), state); @@ -124,24 +132,30 @@ ipc_channel_get_timeout(struct ipc_channel *ch, ev_tstamp timeout) rlist_del_entry(fiber(), state); /* broadcast messsage wakes us up */ - if (!rlist_empty(&ch->bcast)) { - f = rlist_first_entry(&ch->bcast, struct fiber, state); - rlist_del_entry(f, state); - fiber_wakeup(f); + if (ch->bcast) { + fiber_wakeup(ch->bcast); fiber_testcancel(); fiber_setcancellable(cancellable); - return ch->bcast_msg; + res = ch->bcast_msg; + goto exit; } fiber_testcancel(); fiber_setcancellable(cancellable); timeout -= ev_now(loop()) - started; - if (timeout <= 0) - return NULL; + if (timeout <= 0) { + res = NULL; + goto exit; + } + + if (ch->closed) { + res = NULL; + goto exit; + } } - void *res = ch->item[ch->beg]; + res = ch->item[ch->beg]; if (++ch->beg >= ch->size) ch->beg -= ch->size; ch->count--; @@ -152,6 +166,11 @@ ipc_channel_get_timeout(struct ipc_channel *ch, ev_tstamp timeout) fiber_wakeup(f); } +exit: + if (ch->closed && ch->close) { + fiber_wakeup(ch->close); + ch->close = NULL; + } return res; } @@ -162,11 +181,60 @@ ipc_channel_get(struct ipc_channel *ch) return ipc_channel_get_timeout(ch, TIMEOUT_INFINITY); } +static void +ipc_channel_close_waiter(struct ipc_channel *ch, struct fiber *f) +{ + ch->close = fiber(); + + while (ch->close) { + bool cancellable = fiber_setcancellable(true); + fiber_wakeup(f); + fiber_yield(); + ch->close = NULL; + rlist_del_entry(fiber(), state); + fiber_testcancel(); + fiber_setcancellable(cancellable); + } +} + +void +ipc_channel_close(struct ipc_channel *ch) +{ + if (ch->closed) + return; + ch->closed = true; + + struct fiber *f; + while(!rlist_empty(&ch->readers)) { + f = rlist_first_entry(&ch->readers, struct fiber, state); + ipc_channel_close_waiter(ch, f); + } + while(!rlist_empty(&ch->writers)) { + f = rlist_first_entry(&ch->writers, struct fiber, state); + ipc_channel_close_waiter(ch, f); + } + if (ch->bcast) + fiber_wakeup(ch->bcast); +} + +bool +ipc_channel_is_closed(struct ipc_channel *ch) +{ + return ch->closed; +} + int ipc_channel_put_timeout(struct ipc_channel *ch, void *data, ev_tstamp timeout) { + if (ch->closed) { + errno = EBADF; + return -1; + } + bool first_try = true; + int res; + unsigned i; ev_tstamp started = ev_now(loop()); /* channel is full */ while (ch->count >= ch->size) { @@ -189,11 +257,18 @@ ipc_channel_put_timeout(struct ipc_channel *ch, void *data, timeout -= ev_now(loop()) - started; if (timeout <= 0) { errno = ETIMEDOUT; - return -1; + res = -1; + goto exit; + } + + if (ch->closed) { + errno = EBADF; + res = -1; + goto exit; } } - unsigned i = ch->beg; + i = ch->beg; i += ch->count; ch->count++; if (i >= ch->size) @@ -206,7 +281,15 @@ ipc_channel_put_timeout(struct ipc_channel *ch, void *data, rlist_del_entry(f, state); fiber_wakeup(f); } - return 0; + res = 0; +exit: + if (ch->closed && ch->close) { + int save_errno = errno; + fiber_wakeup(ch->close); + ch->close = NULL; + errno = save_errno; + } + return res; } void @@ -230,8 +313,12 @@ ipc_channel_has_writers(struct ipc_channel *ch) int ipc_channel_broadcast(struct ipc_channel *ch, void *data) { + /* do nothing at closed channel */ + if (ch->closed) + return 0; + /* broadcast in broadcast: marasmus */ - if (!rlist_empty(&ch->bcast)) + if (ch->bcast) return 0; /* there is no reader on channel */ @@ -248,13 +335,16 @@ ipc_channel_broadcast(struct ipc_channel *ch, void *data) unsigned cnt = 0; while (!rlist_empty(&ch->readers)) { + if (ch->closed) + break; f = rlist_first_entry(&ch->readers, struct fiber, state); ch->bcast_msg = data; - rlist_add_tail_entry(&ch->bcast, fiber(), state); + ch->bcast = fiber(); fiber_wakeup(f); bool cancellable = fiber_setcancellable(true); fiber_yield(); + ch->bcast = NULL; rlist_del_entry(fiber(), state); fiber_testcancel(); fiber_setcancellable(cancellable); @@ -263,5 +353,10 @@ ipc_channel_broadcast(struct ipc_channel *ch, void *data) break; } + if (ch->closed && ch->close) { + fiber_wakeup(ch->close); + ch->close = NULL; + } + return cnt; } diff --git a/src/ipc.h b/src/ipc.h index ec9e408d0044299f711ccd4fa0bfeb868d28e716..90ea5c3784a0ad4badad7a6ea5bddbf004580019 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -150,7 +150,6 @@ ipc_channel_put_timeout(struct ipc_channel *ch, void *data, void * ipc_channel_get_timeout(struct ipc_channel *ch, ev_tstamp timeout); - /** * @brief return true if channel has reader fibers that wait data * @param channel @@ -165,4 +164,16 @@ ipc_channel_has_readers(struct ipc_channel *ch); bool ipc_channel_has_writers(struct ipc_channel *ch); +/** + * @brief close the channel. Wake up readers and writers (if they exist) + */ +void +ipc_channel_close(struct ipc_channel *ch); + +/** + * @brief return true if the channel is closed + */ +bool +ipc_channel_is_closed(struct ipc_channel *ch); + #endif /* TARANTOOL_IPC_H_INCLUDED */ diff --git a/src/lua/ipc.cc b/src/lua/ipc.cc index 0fac2f731cac415c2641b7e5a67a59049f7371f2..c8c950ec210ba4f7974e3abadb28c025bd2dc992 100644 --- a/src/lua/ipc.cc +++ b/src/lua/ipc.cc @@ -41,6 +41,8 @@ extern "C" { static const char channel_lib[] = "box.ipc.channel"; +#define BROADCAST_MASK (((size_t)1) << (CHAR_BIT * sizeof(size_t) - 1)) + /******************** channel ***************************/ static int @@ -131,35 +133,16 @@ lbox_ipc_channel_put(struct lua_State *L) } ch = lbox_check_channel(L, -top); - lua_getmetatable(L, -top); - - lua_pushstring(L, "rid"); - lua_gettable(L, -2); - - lua_Integer rid = lua_tointeger(L, -1); - if (rid < 0x7FFFFFFF) - rid++; - else - rid = 1; - - lua_pushstring(L, "rid"); /* update object id */ - lua_pushnumber(L, rid); - lua_settable(L, -4); - - lua_pushnumber(L, rid); lua_pushvalue(L, 2); - lua_settable(L, -4); - + size_t vref = luaL_ref(L, LUA_REGISTRYINDEX); int retval; - if (ipc_channel_put_timeout(ch, (void *)rid, timeout) == 0) { + if (ipc_channel_put_timeout(ch, (void *)vref, timeout) == 0) { retval = 1; } else { - /* put timeout */ + /* timed out or closed */ + luaL_unref(L, LUA_REGISTRYINDEX, vref); retval = 0; - lua_pushnumber(L, rid); - lua_pushnil(L); - lua_settable(L, -4); } lua_settop(L, top); @@ -188,30 +171,20 @@ lbox_ipc_channel_get(struct lua_State *L) struct ipc_channel *ch = lbox_check_channel(L, 1); - lua_Integer rid = (lua_Integer)ipc_channel_get_timeout(ch, timeout); + size_t vref = (size_t)ipc_channel_get_timeout(ch, timeout); - if (!rid) { + if (!vref) { + /* timed out or closed */ lua_pushnil(L); return 1; } - - lua_getmetatable(L, 1); - - lua_pushstring(L, "broadcast_message"); - lua_gettable(L, -2); - - if (lua_isnil(L, -1)) { /* common messages */ - lua_pop(L, 1); /* nil */ - - lua_pushnumber(L, rid); /* extract and delete value */ - lua_gettable(L, -2); - - lua_pushnumber(L, rid); - lua_pushnil(L); - lua_settable(L, -4); + if (vref & BROADCAST_MASK) { + vref &= ~BROADCAST_MASK; + lua_rawgeti(L, LUA_REGISTRYINDEX, vref); + return 1; } - - lua_remove(L, -2); /* cleanup stack (metatable) */ + lua_rawgeti(L, LUA_REGISTRYINDEX, vref); + luaL_unref(L, LUA_REGISTRYINDEX, vref); return 1; } @@ -223,30 +196,17 @@ lbox_ipc_channel_broadcast(struct lua_State *L) if (lua_gettop(L) != 2) luaL_error(L, "usage: channel:broadcast(variable)"); - ch = lbox_check_channel(L, -2); + ch = lbox_check_channel(L, 1); if (!ipc_channel_has_readers(ch)) return lbox_ipc_channel_put(L); - lua_getmetatable(L, -2); /* 3 */ - - lua_pushstring(L, "broadcast_message"); /* 4 */ - - /* save old value */ - lua_pushstring(L, "broadcast_message"); - lua_gettable(L, 3); /* 5 */ - lua_pushstring(L, "broadcast_message"); /* save object */ lua_pushvalue(L, 2); - lua_settable(L, 3); - - int count = ipc_channel_broadcast(ch, (void *)1); - - lua_settable(L, 3); - - lua_pop(L, 1); /* stack cleanup */ + size_t vref = luaL_ref(L, LUA_REGISTRYINDEX); + int count = ipc_channel_broadcast(ch, (void *)(vref | BROADCAST_MASK)); + luaL_unref(L, LUA_REGISTRYINDEX, vref); lua_pushnumber(L, count); - return 1; } @@ -270,6 +230,29 @@ lbox_ipc_channel_has_writers(struct lua_State *L) return 1; } +static int +lbox_ipc_channel_close(struct lua_State *L) +{ + if (lua_gettop(L) != 1) + luaL_error(L, "usage: channel:close()"); + struct ipc_channel *ch = lbox_check_channel(L, 1); + ipc_channel_close(ch); + return 0; +} + +static int +lbox_ipc_channel_is_closed(struct lua_State *L) +{ + if (lua_gettop(L) != 1) + luaL_error(L, "usage: channel:is_closed()"); + struct ipc_channel *ch = lbox_check_channel(L, 1); + if (ipc_channel_is_closed(ch)) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + return 1; +} + void tarantool_lua_ipc_init(struct lua_State *L) { @@ -282,6 +265,8 @@ tarantool_lua_ipc_init(struct lua_State *L) {"broadcast", lbox_ipc_channel_broadcast}, {"has_readers", lbox_ipc_channel_has_readers}, {"has_writers", lbox_ipc_channel_has_writers}, + {"close", lbox_ipc_channel_close}, + {"is_closed", lbox_ipc_channel_is_closed}, {NULL, NULL} }; luaL_register_type(L, channel_lib, channel_meta); @@ -291,7 +276,6 @@ tarantool_lua_ipc_init(struct lua_State *L) {NULL, NULL} }; - lua_getfield(L, LUA_GLOBALSINDEX, "box"); lua_pushstring(L, "ipc"); @@ -300,4 +284,3 @@ tarantool_lua_ipc_init(struct lua_State *L) lua_settable(L, -3); lua_pop(L, 1); } - diff --git a/test/box/ipc.result b/test/box/ipc.result index 9999e0b4c2f94860dbabcb06671aeebfe70daa21..f39009cd526e198bab420042babafa6cc0dd9d53 100644 --- a/test/box/ipc.result +++ b/test/box/ipc.result @@ -299,3 +299,81 @@ buffer - - tfbr2 - '45' ... +ch = box.ipc.channel(1) +--- +... +ch:is_closed() +--- +- false +... +passed = false +--- +... +type(box.fiber.wrap(function() if ch:get() == nil then passed = true end end)) +--- +- userdata +... +ch:close() +--- +... +passed +--- +- true +... +ch:get() +--- +- null +... +ch:get() +--- +- null +... +ch:put(10) +--- +- false +... +ch:is_closed() +--- +- true +... +ch = box.ipc.channel(1) +--- +... +ch:put(true) +--- +- true +... +ch:is_closed() +--- +- false +... +passed = false +--- +... +type(box.fiber.wrap(function() if ch:put(true) == false then passed = true end end)) +--- +- userdata +... +ch:close() +--- +... +passed +--- +- true +... +ch:get() +--- +- null +... +ch:get() +--- +- null +... +ch:put(10) +--- +- false +... +ch:is_closed() +--- +- true +... diff --git a/test/box/ipc.test b/test/box/ipc.test new file mode 100644 index 0000000000000000000000000000000000000000..074af0c3a3697c0d537e9560a0990bc6685a794e --- /dev/null +++ b/test/box/ipc.test @@ -0,0 +1,62 @@ +# encoding: tarantool +# +import sys + +exec admin "lua ch = box.ipc.channel()" +exec admin "lua ch:is_full()" +exec admin "lua ch:is_empty()" +exec admin "lua ch:get(.1)" +exec admin "lua ch:put()" +exec admin "lua ch:put('test')" +exec admin "lua ch:get()" +exec admin "lua ch:get('wrong timeout')" +exec admin "lua ch:get(-10)" +exec admin "lua ch:put(234)" +exec admin "lua ch:put(345, .5)" +exec admin "lua ch:is_full()" +exec admin "lua ch:is_empty()" +exec admin "lua buffer = {}" +exec admin "lua tfbr = box.fiber.create(function() box.fiber.detach() while true do table.insert(buffer, ch:get()) end end)" +exec admin "lua box.fiber.resume(tfbr)" +exec admin "lua for i = 1, 10 do print(i, ' ', ch:put(i, 0.1)) end" +exec admin "lua ch:has_readers()" +exec admin "lua ch:has_writers()" +exec admin "lua box.fiber.cancel(tfbr)" + +exec admin "lua ch:has_readers()" +exec admin "lua ch:has_writers()" +exec admin "lua ch:put(box.info.pid)" +exec admin "lua ch:is_full()" +exec admin "lua ch:is_empty()" +exec admin "lua ch:get(box.info.pid) == box.info.pid" +exec admin "lua for i, v in pairs(buffer) do print(v) end" + +exec admin "lua ch:is_empty()" +exec admin "lua ch:broadcast()" +exec admin "lua ch:broadcast(123)" +exec admin "lua ch:get()" + +exec admin "lua ch:is_full()" +exec admin "lua ch:is_empty()" +exec admin "lua tfbr = box.fiber.create(function() box.fiber.detach() while true do local v = ch:get() table.insert(buffer, 'tfbr - ' .. tostring(v)) end end)" +exec admin "lua box.fiber.resume(tfbr)" +exec admin "lua tfbr2 = box.fiber.create(function() box.fiber.detach() while true do local v = ch:get() table.insert(buffer, 'tfbr2 - ' .. tostring(v)) end end)" +exec admin "lua box.fiber.resume(tfbr2)" + +exec admin "lua buffer = {}" + +exec admin "lua for i, v in pairs(buffer) do print(v) end" +exec admin "lua ch:is_full()" +exec admin "lua ch:is_empty()" +exec admin "lua ch:put(1)" +exec admin "lua ch:put(2)" +exec admin "lua ch:put(3)" +exec admin "lua ch:put(4)" +exec admin "lua ch:put(5)" +exec admin "lua ch:broadcast('broadcast message!')" +exec admin "lua for i = 35, 45 do print(ch:put(i)) end" + + +exec admin "lua for i, v in pairs(buffer) do print(v) end" + + diff --git a/test/box/ipc.test.lua b/test/box/ipc.test.lua index fe793d9350f7b899ee1806606263aa352bfb6991..a7ce76657977412d2746262af6ddc49f351991a8 100644 --- a/test/box/ipc.test.lua +++ b/test/box/ipc.test.lua @@ -85,3 +85,26 @@ t = {} for i = 35, 45 do table.insert(t, ch:put(i)) end t buffer + +ch = box.ipc.channel(1) +ch:is_closed() +passed = false +type(box.fiber.wrap(function() if ch:get() == nil then passed = true end end)) +ch:close() +passed +ch:get() +ch:get() +ch:put(10) +ch:is_closed() + +ch = box.ipc.channel(1) +ch:put(true) +ch:is_closed() +passed = false +type(box.fiber.wrap(function() if ch:put(true) == false then passed = true end end)) +ch:close() +passed +ch:get() +ch:get() +ch:put(10) +ch:is_closed()