A fiber is a set of instructions which are executed with cooperative
multitasking. Fibers managed by the fiber module are associated with
a user-supplied function called the fiber function.

A fiber has three possible states: running, suspended or dead.
When a fiber is created with fiber.create(), it is running.
When a fiber yields control with fiber.sleep(), it is suspended.
When a fiber ends (because the fiber function ends), it is dead.

All fibers are part of the fiber registry. This registry can be searched
with fiber.find() - via fiber id (fid), which is a numeric
identifier.

The other potential problem comes from fibers which never get scheduled, because
they are not subscribed to any events, or because no relevant events occur. Such
morphing fibers can be killed with fiber.kill() at any time,
since fiber.kill() sends an asynchronous wakeup event to the
fiber, and fiber.testcancel() is checked whenever such
a wakeup event occurs.

Like all Lua objects, dead fibers are garbage collected. The garbage collector
frees pool allocator memory owned by the fiber, resets all fiber data, and
returns the fiber (now called a fiber carcass) to the fiber pool. The carcass
can be reused when another fiber is created.

A fiber has all the features of a Lua coroutine and all the programming
concepts that apply for Lua coroutines will apply for fibers as well. However,
Tarantool has made some enhancements for fibers and has used fibers internally.
So, although use of coroutines is possible and supported, use of fibers is
recommended.

self – fiber object, for example the fiber object returned
by fiber.create

Return:

name of the fiber.

Rtype:

string

Example:

tarantool> fiber.self():name()----interactive...

fiber_object:name(name)

Change the fiber name. By default a Tarantool server’s
interactive-mode fiber is named „interactive“ and new
fibers created due to fiber.create are named „lua“.
Giving fibers distinct names makes it easier to
distinguish them when using fiber.info.

Параметры:

self – fiber object, for example the fiber
object returned by fiber.create

Cancel a fiber. Running and suspended fibers can be cancelled.
After a fiber has been cancelled, attempts to operate on it will
cause errors, for example fiber_object:id()
will cause error:thefiberisdead.

Параметры:

self – fiber object, for example the fiber
object returned by fiber.create

Return:

nil

Possible errors: cancel is not permitted for the specified fiber object.

Example:

tarantool> fiber.self():cancel()-- kill self, may make program send----error:fiber is cancelled...

Local storage within the fiber. The storage can contain any number of
named values, subject to memory limitations. Naming may be done with
fiber_object.storage.name or fiber_object.storage['name'].
or with a number fiber_object.storage[number].
Values may be either numbers or strings. The storage is garbage-collected
when fiber_object:cancel() happens.

current system time (in seconds since the epoch) as a Lua
number. The time is taken from the event loop clock,
which makes this call very cheap, but still useful for
constructing artificial tuple keys.

Make the function which will be associated with the fiber. This function
contains an infinite loop (while0==0 is always true). Each iteration
of the loop adds 1 to a global variable named gvar, then goes to sleep for
2 seconds. The sleep causes an implicit fiber.yield().

Make a fiber, associate function_x with the fiber, and start function_x.
It will immediately «detach» so it will be running independently of the caller.

tarantool> gvar=0tarantool> fiber_of_x=fiber.create(function_x)---...

Get the id of the fiber (fid), to be used in later displays.

tarantool> fid=fiber_of_x:id()---...

Pause for a while, while the detached function runs. Then … Display the fiber
id, the fiber status, and gvar (gvar will have gone up a bit depending how long
the pause lasted). The status is suspended because the fiber spends almost all
its time sleeping or yielding.

Pause for a while, while the detached function runs. Then … Cancel the fiber.
Then, once again … Display the fiber id, the fiber status, and gvar (gvar
will have gone up a bit more depending how long the pause lasted). This time
the status is dead because the cancel worked.

Message exchange is synchronous. The channel is garbage collected when no one is
using it, as with any other Lua object. Use object-oriented syntax, for example
channel:put(message) rather than fiber.channel.put(message).

Send a message using a channel. If the channel is full,
channel:put() waits until there is a free slot in the channel.

Параметры:

message (lua-value) – what will be sent, usually a string or number or table

timeout (number) – maximum number of seconds to wait for a slot to become free

Return:

If timeout is specified, and there is no free slot in the
channel for the duration of the timeout, then the return value
is false. If the channel is closed, then the return value is false.
Otherwise, the return value is true, indicating success.

Fetch and remove a message from a channel. If the channel is empty,
channel:get() waits for a message.

Параметры:

timeout (number) – maximum number of seconds to wait for a message

Return:

If timeout is specified, and there is no message in the
channel for the duration of the timeout, then the return
value is nil. If the channel is closed, then the
return value is nil. Otherwise, the return value is
the message placed on the channel by channel:put().

This example should give a rough idea of what some functions for fibers should
look like. It’s assumed that the functions would be referenced in
fiber.create().

fiber=require('fiber')channel=fiber.channel(10)functionconsumer_fiber()whiletruedolocaltask=channel:get()...endendfunctionconsumer2_fiber()whiletruedo-- 10 secondslocaltask=channel:get(10)iftask~=nilthen...else-- timeoutendendendfunctionproducer_fiber()whiletruedotask=box.space...:select{...}...ifchannel:is_empty()then-- channel is emptyendifchannel:is_full()then-- channel is fullend...ifchannel:has_readers()then-- there are some fibers-- that are waiting for dataend...ifchannel:has_writers()then-- there are some fibers-- that are waiting for readersendchannel:put(task)endendfunctionproducer2_fiber()whiletruedotask=box.space...select{...}-- 10 secondsifchannel:put(task,10)then...else-- timeoutendendend

Assume that a tarantool instance is running and listening for connections on
localhost port 3301. Assume that guest users have privileges to connect. We will
use the tarantoolctl utility to start two clients.

The job will hang because cond:wait() – without an optional timeout
argument – will go to sleep until the condition variable changes.

On terminal #2, say

$ tarantoolctl connect '3301'tarantool> cond:signal()

Now look again at terminal #1. It will show that the waiting stopped, and the
cond:wait() function returned true.

This example depended on the use of a global conditional variable with the
arbitrary name cond. In real life, programmers would make sure to use
different conditional variable names for different applications.