Skip to content
Snippets Groups Projects
user avatar
Vladislav Shpilevoy authored
SWIM as a monitoring module is hard to use without an ability to
subscribe on events. Otherwise a user should have polled a SWIM
member table for updates - it would be too inefficient.

This commit exposes an ability to set Lua triggers.

Closes #4250

@TarantoolBot document
Title: SWIM: swim:on_member_event

Now a user can set triggers on member table updates. There is a
function for that, which can be used in one of several ways:
```Lua
swim:on_member_event(new_trigger[, ctx])
```
Add a new trigger on member table update. The function
`new_trigger` will be called on each new member appearance, an
existing member drop, and update. It should take 3 arguments:
first is an updated SWIM member, second is an events object,
third is `ctx` passed as is.

Events object has methods to help a user to determine what event
has happened.
```Lua
local function on_event(member, event, ctx)
    if event:is_new() then
        ...
    elseif event:is_drop() then
        ...
    end

    if event:is_update() then
        -- All next conditions can be
        -- true simultaneously.
        if event:is_new_status() then
            ...
        end
        if event:is_new_uri() then
            ...
        end
        if event:is_new_incarnation() then
            ...
        end
        if event:is_new_payload() then
            ...
        end
    end
end

s:on_member_event(on_event, ctx)
```
Note, that multiple events can happen simultaneously. A user
should be ready to that. Additionally, 'new' and 'drop' never
happen together. But they can happen with 'update', easily.
Especially if there are lots of events, and triggers work too
slow. Then a member can be added and updated after a while, but
still does not reach a trigger.

A remarkable case is 'new' + 'new payload'. This case does not
correlate with triggers speed. The thing is that payload absence
and payload of size 0 are not the same. And sometimes is happens,
that a member is added without a payload. For example, a ping
was received - pings do not carry payload. In such a case the
missed payload is received later eventually. If that matters for
a user's application, it should be ready to that: 'new' does not
mean, that the member already has a payload, and payload size
says nothing about its presence or absence.

Second usage case:
```Lua
swim:on_member_event(nil, old_trigger)
```
Drop an old trigger.

Third usage case:
```Lua
swim:on_member_event(new_trigger, old_trigger[, ctx])
```
Replace an existing trigger in-place, with keeping its position
in the trigger list.

Fourth usage case:
```Lua
swim:on_member_event()
```
Get a list of triggers.

When drop or replace a trigger, a user should be attentive - the
following code does not work:
```Lua
tr = function() ... end
-- Add a trigger.
s:on_member_event(tr)
...
-- Drop a trigger.
s:on_member_event(nil, tr)
```
The last line, if be precise. This is because SWIM wraps user
triggers with an internal closure for parameters preprocessing.
To drop a trigger a user should save result of the first
on_member_event() call.

This code works:
```Lua
tr = function() ... end
-- Add a trigger.
tr_id = s:on_member_event(tr)
...
-- Drop a trigger.
s:on_member_event(nil, tr_id)
```

The triggers are executed one by one in a separate fiber. And
they can yield. These two facts mean that if one trigger sleeps
too long - other triggers wait. It does not block SWIM from doing
its routine operations, but block other triggers.

The last point to remember is that if a member was added and
dropped before its appearance has reached a trigger, then such
a member does not fire triggers at all. A user will not notice
that easy rider member.
6ee11c84
History

Tarantool

Build Status Code Coverage Telegram Slack Gitter Google Groups

https://tarantool.io/en/

Tarantool is an in-memory database and application server.

Key features of the application server:

  • 100% compatible drop-in replacement for Lua 5.1, based on LuaJIT 2.1. Simply use #!/usr/bin/tarantool instead of #!/usr/bin/lua in your script.
  • full support for Lua modules and a rich set of own modules, including cooperative multitasking, non-blocking I/O, access to external databases, etc

Key features of the database:

  • ANSI SQL, including views, joins, referential and check constraints
  • MsgPack data format and MsgPack based client-server protocol
  • two data engines: 100% in-memory with optional persistence and an own implementation of LSM-tree, to use with large data sets
  • multiple index types: HASH, TREE, RTREE, BITSET
  • asynchronous master-master replication
  • authentication and access control
  • the database is just a C extension to the application server and can be turned off

Supported platforms are Linux/x86 and FreeBSD/x86, Mac OS X.

Tarantool is ideal for data-enriched components of scalable Web architecture: queue servers, caches, stateful Web applications.

To download and install Tarantool as a binary package for your OS, please visit https://tarantool.io/en/download/.

To build Tarantool from source, see detailed instructions in the Tarantool documentation at https://tarantool.io/en/doc/2.1/dev_guide/building_from_source/.

Please report bugs at https://github.com/tarantool/tarantool/issues We also warmly welcome your feedback in the discussion mailing list, tarantool@googlegroups.com.

Thank you for your interest in Tarantool!