Модуль fiber¶
The fiber
module allows for creating, running and managing fibers.
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.
A runaway fiber can be stopped with fiber_object.cancel.
However, fiber_object.cancel is advisory — it works
only if the runaway fiber calls fiber.testcancel()
occasionally. Most box.*
functions, such as
box.space…delete() or
box.space…update(), do call
fiber.testcancel() but
box.space…select{} does not. In practice, a runaway
fiber can only become unresponsive if it does many computations and does not
check whether it has been cancelled.
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.
-
fiber.
create
(function[, function-arguments])¶ Create and start a fiber. The fiber is created and begins to run immediately.
Параметры: - function – the function to be associated with the fiber
- function-arguments – what will be passed to function
Return: created fiber object
Rtype: userdata
Example:
tarantool> fiber = require('fiber') --- ... tarantool> function function_name() > fiber.sleep(1000) > end --- ... tarantool> fiber_object = fiber.create(function_name) --- ...
-
fiber.
self
()¶ Return: fiber object for the currently scheduled fiber. Rtype: userdata Example:
tarantool> fiber.self() --- - status: running name: interactive id: 101 ...
-
fiber.
find
(id)¶ Параметры: - id – numeric identifier of the fiber.
Return: fiber object for the specified fiber.
Rtype: userdata
Example:
tarantool> fiber.find(101) --- - status: running name: interactive id: 101 ...
-
fiber.
sleep
(time)¶ Yield control to the transaction processor thread and sleep for the specified number of seconds. Only the current fiber can be made to sleep.
Параметры: - time – number of seconds to sleep.
Example:
tarantool> fiber.sleep(1.5) --- ...
-
fiber.
yield
()¶ Yield control to the scheduler. Equivalent to fiber.sleep(0).
Example:
tarantool> fiber.yield() --- ...
-
fiber.
status
()¶ Return the status of the current fiber.
Return: the status of fiber
. One of: “dead”, “suspended”, or “running”.Rtype: string Example:
tarantool> fiber.status() --- - running ...
-
fiber.
info
()¶ Return information about all fibers.
Return: number of context switches, backtrace, id, total memory, used memory, name for each fiber. Rtype: table Example:
tarantool> fiber.info() --- - 101: csw: 7 backtrace: [] fid: 101 memory: total: 65776 used: 0 name: interactive ...
-
fiber.
kill
(id)¶ Locate a fiber by its numeric id and cancel it. In other words, fiber.kill() combines fiber.find() and fiber_object:cancel().
Параметры: - id – the id of the fiber to be cancelled.
Exception: the specified fiber does not exist or cancel is not permitted.
Example:
tarantool> fiber.kill(fiber.id()) -- kill self, may make program end --- - error: fiber is cancelled ...
-
fiber.
testcancel
()¶ Check if the current fiber has been cancelled and throw an exception if this is the case.
Example:
tarantool> fiber.testcancel() --- - error: fiber is cancelled ...
-
object
fiber_object
¶ -
fiber_object:
id
()¶ Параметры: - self – fiber object, for example the fiber object returned by fiber.create
Return: id of the fiber.
Rtype: number
Example:
tarantool> fiber_object = fiber.self() --- ... tarantool> fiber_object:id() --- - 101 ...
-
fiber_object:
name
()¶ Параметры: - 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
- name (string) – the new name of the fiber.
Return: nil
Example:
tarantool> fiber.self():name('non-interactive') --- ...
-
fiber_object:
status
()¶ Return the status of the specified fiber.
Параметры: - self – fiber object, for example the fiber object returned by fiber.create
Return: the status of fiber. One of: “dead”, “suspended”, or “running”.
Rtype: string
Example:
tarantool> fiber.self():status() --- - running ...
-
fiber_object:
cancel
()¶ 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: the fiber is dead
.Параметры: - 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 ...
-
fiber_object.
storage
¶ 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
orfiber_object.storage['name'].
or with a numberfiber_object.storage[number]
. Values may be either numbers or strings. The storage is garbage-collected whenfiber_object:cancel()
happens.Example:
tarantool> fiber = require('fiber') --- ... tarantool> function f () fiber.sleep(1000); end --- ... tarantool> fiber_function = fiber:create(f) --- - error: '[string "fiber_function = fiber:create(f)"]:1: fiber.create(function, ...): bad arguments' ... tarantool> fiber_function = fiber.create(f) --- ... tarantool> fiber_function.storage.str1 = 'string' --- ... tarantool> fiber_function.storage['str1'] --- - string ... tarantool> fiber_function:cancel() --- ... tarantool> fiber_function.storage['str1'] --- - error: '[string "return fiber_function.storage[''str1'']"]:1: the fiber is dead' ...
See also box.session.storage.
-
-
fiber.
time
()¶ Return: 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. Rtype: num Example:
tarantool> fiber.time(), fiber.time() --- - 1448466279.2415 - 1448466279.2415 ...
-
fiber.
time64
()¶ Return: current system time (in microseconds since the epoch) as a 64-bit integer. The time is taken from the event loop clock. Rtype: num Example:
tarantool> fiber.time(), fiber.time64() --- - 1448466351.2708 - 1448466351270762 ...
Example Of Fiber Use¶
Make the function which will be associated with the fiber. This function
contains an infinite loop (while 0 == 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().
tarantool> fiber = require('fiber')
tarantool> function function_x()
> gvar = 0
> while 0 == 0 do
> gvar = gvar + 1
> fiber.sleep(2)
> end
> end
---
...
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 = 0
tarantool> 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.
tarantool> print('#', fid, '. ', fiber_of_x:status(), '. gvar=', gvar)
# 102 . suspended . gvar= 399
---
...
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.
tarantool> fiber_of_x:cancel()
---
...
tarantool> print('#', fid, '. ', fiber_of_x:status(), '. gvar=', gvar)
# 102 . dead . gvar= 421
---
...