Skip to content
Snippets Groups Projects
Commit 87934fe3 authored by bigbes's avatar bigbes
Browse files

[documentation] CR for pgulutzan patches

parent 8b92eb26
No related branches found
No related tags found
No related merge requests found
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
Atomic execution Atomic execution
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
In several places in this manual it's been noted that Lua processes occur in fibers on a In several places in this manual it's been noted that Lua processes occur in
single thread. That is why there can be a guarantee of execution atomicity. fibers on a single thread. That is why there can be a guarantee of execution
That requires emphasis. atomicity. That requires emphasis.
.. _cooperative_multitasking: .. _cooperative_multitasking:
...@@ -15,26 +15,23 @@ That requires emphasis. ...@@ -15,26 +15,23 @@ That requires emphasis.
Cooperative multitasking environment Cooperative multitasking environment
=========================================================== ===========================================================
Tarantool uses cooperative multitasking: unless a Tarantool uses cooperative multitasking: unless a running fiber deliberately
running fiber deliberately yields control, it is not yields control, it is not preempted by some other fiber. But a running fiber
preempted by some other fiber. will deliberately yield when it encounters a "yield point": an explicit
But a running fiber will deliberately yield when it encounters a `yield()` request, or an implicit yield due to an operating-system call. Any
"yield point": an explicit yield() request, or an implicit system call which can block will be performed asynchronously, and any running
yield due to an operating-system call. fiber which must wait for a system call will be preempted so that another
Any system call which can block will be performed asynchronously, ready-to-run fiber takes its place and becomes the new running fiber. This model
and any running fiber which must wait for a system call will be makes all programmatic locks unnecessary: cooperative multitasking ensures that
preempted so that another ready-to-run fiber takes its place and there will be no concurrency around a resource, no race conditions, and
becomes the new running fiber. no memory consistency issues.
This model makes all programmatic locks unnecessary:
cooperative multitasking ensures that there will be no concurrency around a resource, When requests are small, for example simple UPDATE or INSERT or DELETE or SELECT,
no race conditions, and no memory consistency issues. fiber scheduling is fair: it takes only a little time to process the request,
schedule a disk write, and yield to a fiber serving the next client.
When requests are small, for example simple UPDATE or INSERT or DELETE or SELECT, fiber
scheduling is fair: it takes only a little time to process the request, schedule However, a function might perform complex computations or might be written in
a disk write, and yield to a fiber serving the next client. such a way that yields do not occur for a long time. This can lead to unfair
However, a function might perform complex computations or might be written in such a
way that yields do not occur for a long time. This can lead to unfair
scheduling, when a single client throttles the rest of the system, or to scheduling, when a single client throttles the rest of the system, or to
apparent stalls in request processing. Avoiding this situation is the apparent stalls in request processing. Avoiding this situation is the
responsibility of the function's author. For the default memtx storage engine responsibility of the function's author. For the default memtx storage engine
...@@ -44,15 +41,14 @@ most of the box calls, including the data-change requests ...@@ -44,15 +41,14 @@ most of the box calls, including the data-change requests
:func:`box.space...delete <space_object.delete>`, are yield points; :func:`box.space...delete <space_object.delete>`, are yield points;
however, :func:`box.space...select <space_object.select>` is not. however, :func:`box.space...select <space_object.select>` is not.
Note re storage engine: sophia has different rules: Note re storage engine: sophia has different rules: insert or update or delete
insert or update or delete will very rarely cause a yield, will very rarely cause a yield, but select can cause a yield.
but select can cause a yield.
In the absence of transactions, any function that contains yield points In the absence of transactions, any function that contains yield points may see
may see changes in the database state caused by fibers that preempt. changes in the database state caused by fibers that preempt. Then the only safe
Then the only safe atomic functions for memtx databases would be atomic functions for memtx databases would be functions which contain only one
functions which contain only one database request, or functions which database request, or functions which contain a select request followed by a
contain a select request followed by a data-change request. data-change request.
At this point an objection could arise: "It's good that a single data-change At this point an objection could arise: "It's good that a single data-change
request will commit and yield, but surely there are times when multiple request will commit and yield, but surely there are times when multiple
...@@ -86,8 +82,8 @@ To ensure they are sent as a single block: put them in a function, or put them a ...@@ -86,8 +82,8 @@ To ensure they are sent as a single block: put them in a function, or put them a
on one line, or use a delimiter so that multi-line requests are handled together. on one line, or use a delimiter so that multi-line requests are handled together.
**All database operations in a transaction should use the same storage engine**. **All database operations in a transaction should use the same storage engine**.
It is not safe to access tuple sets that are defined with {engine='sophia'} It is not safe to access tuple sets that are defined with ``{engine='sophia'}``
and also access tuple sets that are defined with {engine='memtx'}, and also access tuple sets that are defined with ``{engine='memtx'}``,
in the same transaction. in the same transaction.
=========================================================== ===========================================================
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
It was explained :ref:`earlier <yields_must_happen>` that memtx does not "yield" on a select request, It was explained :ref:`earlier <yields_must_happen>` that memtx does not "yield" on a select request,
it yields only on data-change requests. However, sophia does yield on a select it yields only on data-change requests. However, sophia does yield on a select
request, or on an equivalent such as get() or pairs(). This has significance request, or on an equivalent such as get() or pairs(). This has significance
for :ref:`cooperative multitasking <cooperative_multitasking>`. for :ref:`cooperative multitasking <cooperative_multitasking>`.
For more about sophia, see Appendix E :ref:`sophia <sophia>`. For more about sophia, see Appendix E :ref:`sophia <sophia>`.
...@@ -63,8 +63,6 @@ If the insert fails, the program will print "Insert failed" and an error number. ...@@ -63,8 +63,6 @@ If the insert fails, the program will print "Insert failed" and an error number.
Here are notes corresponding to comments in the example program. Here are notes corresponding to comments in the example program.
.. _c_setup:
**SETUP:** The setup begins by creating a stream. **SETUP:** The setup begins by creating a stream.
.. code-block:: c .. code-block:: c
...@@ -86,8 +84,6 @@ Function description: ...@@ -86,8 +84,6 @@ Function description:
`struct tnt_stream *tnt_net(struct tnt_stream *s)` `struct tnt_stream *tnt_net(struct tnt_stream *s)`
`int tnt_set(struct tnt_stream *s, int option, variant option-value)` `int tnt_set(struct tnt_stream *s, int option, variant option-value)`
.. _c_connect:
**CONNECT:** Now that the stream named ``tnt`` exists and is associated with a **CONNECT:** Now that the stream named ``tnt`` exists and is associated with a
URI, this example program can connect to the server. URI, this example program can connect to the server.
...@@ -107,8 +103,6 @@ The connect might fail for a variety of reasons, such as: ...@@ -107,8 +103,6 @@ The connect might fail for a variety of reasons, such as:
the server is not running, or the URI contains an invalid password. the server is not running, or the URI contains an invalid password.
If the connect fails, the return value will be -1. If the connect fails, the return value will be -1.
.. _c_make_request:
**MAKE REQUEST:** Most requests require passing a structured value, such as **MAKE REQUEST:** Most requests require passing a structured value, such as
the contents of a tuple. the contents of a tuple.
...@@ -133,8 +127,6 @@ Function description: ...@@ -133,8 +127,6 @@ Function description:
ssize_t tnt_object_format(struct tnt_stream \*s, const char \*fmt, ...) ssize_t tnt_object_format(struct tnt_stream \*s, const char \*fmt, ...)
.. _c_send_request:
**SEND REQUEST:** The database-manipulation requests are analogous to the **SEND REQUEST:** The database-manipulation requests are analogous to the
requests in the box library. requests in the box library.
...@@ -160,8 +152,6 @@ Function description: ...@@ -160,8 +152,6 @@ Function description:
ssize_t tnt_update(struct tnt_stream \*s, uint32_t space, uint32_t index, ssize_t tnt_update(struct tnt_stream \*s, uint32_t space, uint32_t index,
struct tnt_stream \*key, struct tnt_stream \*ops) struct tnt_stream \*key, struct tnt_stream \*ops)
.. _c_get_reply:
**GET REPLY:** For most requests the client will receive a reply containing some indication **GET REPLY:** For most requests the client will receive a reply containing some indication
whether the result was successful, and a set of tuples. whether the result was successful, and a set of tuples.
...@@ -183,8 +173,6 @@ Function description: ...@@ -183,8 +173,6 @@ Function description:
tnt->read_reply(struct tnt_stream \*s, struct tnt_reply \*r) tnt->read_reply(struct tnt_stream \*s, struct tnt_reply \*r)
void tnt_reply_free(struct tnt_reply \*r) void tnt_reply_free(struct tnt_reply \*r)
.. _c_teardown:
**TEARDOWN:** When a session ends, the connection that was made with **TEARDOWN:** When a session ends, the connection that was made with
tnt_connect() should be closed and the objects that were made in the setup tnt_connect() should be closed and the objects that were made in the setup
should be destroyed. should be destroyed.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment