Skip to content

Commit

Permalink
Update accumulator docs
Browse files Browse the repository at this point in the history
  • Loading branch information
chrzaszcz committed Feb 16, 2023
1 parent 391a894 commit 245c279
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 24 deletions.
22 changes: 15 additions & 7 deletions doc/developers-guide/accumulators.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Accumulators

XMPP stanza processing starts in the `ejabberd_c2s` module, which receives the stanza from a socket, or in `ejabberd_s2s_in` which receives stanzas from federated XMPP clusters.
XMPP stanza processing starts in the `mongoose_c2s` module, which receives the stanza from a socket, or in `ejabberd_s2s_in` which receives stanzas from federated XMPP clusters.
The stanza is processed and eventually it and/or other messages are sent out, either to the original sender, to another c2s process within the same MongooseIM installation, or to another XMPP server.

At the beginning of the main processing chain an accumulator is created containing following set of keys:
Expand All @@ -11,6 +11,8 @@ At the beginning of the main processing chain an accumulator is created containi
* `origin_location` - `{Module, Function Line}` - A place in the code where the accumulator was created.
* `origin_stanza` - Original stanza that triggered the processing (in a binary).
* `lserver` - Nameprepped domain of the processing context.
* `host_type` - Host type that the domain belongs to.
* `statem_acc` - Data related to the C2S state machine.
* `stanza` - A map with information about the stanza being routed. May be missing in some processing chains (when they are not triggered by a stanza)!
* `element` - `exml:element()` with the current stanza being routed.
* `from_jid`, `to_jid` - `jid:jid()` with the sender and the recipient.
Expand Down Expand Up @@ -40,6 +42,8 @@ A constructor for accumulators. `new_acc_params()` is a map with following suppo

* `location` - Should be a `{Module, Function, Line}` tuple (may be constructed with `?LOCATION` macro from `mongoose.hrl`). Its format is not enforced by the acc logic but Dialyzer will most probably complain about any other type.
* `lserver` - Nameprepped domain of the processing context.
* `host_type` (optional) - Host type that the domain belongs to.
* `statem_acc` (optional) - Data related to the C2S state machine.
* `element` (optional) - If present, it will be used as a source for the `stanza` map.
* `from_jid`, `to_jid` (optional) - Values used to override `from` and `to` attributes of the `element`, respectively.

Expand All @@ -53,9 +57,11 @@ While allowed, stanza-less accumulators usage should be avoided.
* `ref(t())`
* `timestamp(t())`
* `lserver(t())`
* `host_type(t())`
* `element(t())`
* `to_jid(t())`
* `from_jid(t())`
* `get_statem_acc(t())`
* `packet(t())` - Returns an `mongoose_c2s:packet()` if there is a stanza in the accumulator.
* `stanza_name(t())` - Returns `name` value from `stanza` map.
* `stanza_type(t())` - Returns `type` value from `stanza` map.
Expand All @@ -80,15 +86,16 @@ There is no scope protection, so every module may access all namespaces and keys

### Stripping

Accumulator is used mostly to cache values for reuse within a c2s process; when it goes out to somewhere else, it is stripped of all unnecessary attributes except for:
Accumulator is used mostly to cache values for reuse within a c2s process; when it goes out to somewhere else, it is stripped of all unnecessary attributes except for the non-strippable ones, e.g.

* `ref`
* `timestamp`
* `origin_pid`
* `origin_location`
* `origin_stanza`
* `non_strippable` - A set of permanent `NS:Key` pairs.

For a complete list, see `mongoose_acc:default_non_strippable/0`

If you want it to carry some additional values along with it, please use a dedicated api for setting "permanent" fields:

```erlang
Expand All @@ -105,7 +112,8 @@ There are also many cached values which are not valid anymore when user changes

In order to strip an accumulator, please use `strip(strip_params(), t())`, where `strip_params()` is a map of:

* `lserver` - New host context. Obviously, may be equal to the old value.
* `lserver` - New domain. Obviously, may be equal to the old value.
* `host_type` - Host type associated with the new domain, if there is one.
* `element`, `from_jid`, `to_jid` - The same rules apply as in `update_stanza/2`.

## Main principles of an accumulator processing
Expand All @@ -124,7 +132,7 @@ When it comes to the accumulators, the following rules apply:
* Avoid passing superfluous arguments to handlers - e.g. an `LServer` in hook args is redundant since it is already present in the accumulator.

Most handlers have already been modified so that they accept an instance of `mongoose_acc:t()` as the first argument and return value by storing it inside it.
How the accumulator is used within a module is up to the implementors of the module.
How the accumulator is used within a module is up to the implementers of the module.

## IQs and accumulators

Expand All @@ -145,8 +153,8 @@ According to the current `mongoose_privacy:privacy_check_packet` implementation,

### Tracing

`origin_stanza` field is fully immutable for the lifespan of a single accumulator, so it's easier to correlate one of the stanzas sent by a client with some "unexpected" stanza routed from a completely different part of a server.
There are many places in the server, where an accumulator may be created, so `origin_location` makes it much easier to find out what event has triggered the processing.
`origin_pid` and `origin_location` fields are immutable for the lifespan of a single accumulator.
There are many places in the server, where an accumulator may be created, so `origin_location` makes it much easier to find out what event has triggered the processing, and `origin_pid` identifies the process in which it happened.

### Performance measurement

Expand Down
51 changes: 34 additions & 17 deletions doc/developers-guide/hooks_description.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ The stanza can be filtered out (in case the handler returns `drop`), left unchan

### Handler examples

These hooks are handled by the following modules, listed in the order of execution, i.e. sorted according to increasing priorities.
These hooks are handled by the following modules:

* [`mod_pubsub`](../modules/mod_pubsub.md) - for each subscription authorization form sent by a node owner, the subscription state is updated, and the stanza is dropped.
* [`mod_domain_isolation`](../modules/mod_domain_isolation.md) - filters out cross-domain stanzas.
* [`mod_smart_markers`](../modules/mod_smart_markers.md) - filters out chat markers, because they are handled separately by the module.
* [`mod_mam`](../modules/mod_mam.md) - stores incoming messages in the archive, and adds MAM-related elements to the message.
* [`mod_event_pusher`](../modules/mod_event_pusher.md) - sends push notifications for incoming stanzas.
* [`mod_inbox`](../modules/mod_inbox.md) - stores incoming messages to the recipient's inbox.
* [`mod_mam`](../modules/mod_mam.md) - stores incoming messages in the archive, and adds MAM-related elements to the message.
* [`mod_pubsub`](../modules/mod_pubsub.md) - for each subscription authorization form sent by a node owner, the subscription state is updated, and the stanza is dropped.
* [`mod_smart_markers`](../modules/mod_smart_markers.md) - filters out chat markers, because they are handled separately by the module.

## `user_receive_*`

Expand Down Expand Up @@ -140,7 +140,7 @@ mongoose_hooks:offline_message_hook(Acc, From, To, Packet)

This hook is handled by the following modules, listed in the order of execution:

* [`mod_offline_chatmarkers`](../modules/mod_offline_chatmarkers.md) - for chat marker messages, the handler stores them and returns `{stop, Acc}`, preventing further handlers from being called. Such messages are then processed by `mod_smart_markers`.
* `mod_offline_chatmarkers` - for chat marker messages, the handler stores them and returns `{stop, Acc}`, preventing further handlers from being called.

* [`mod_offline`](../modules/mod_offline.md) - stores messages in a persistent way until the recipient comes online, and the message can be successfully delivered. The handler returns `{stop, Acc}` for all messages, preventing further handlers from being called.

Expand Down Expand Up @@ -207,23 +207,19 @@ This is the perfect place to plug in custom security control.

## Other hooks

* acc_room_affiliations
* adhoc_local_commands
* adhoc_sm_commands
* amp_check_condition
* amp_determine_strategy
* amp_verify_support
* anonymous_purge_hook
* auth_failed
* c2s_broadcast_recipients
* c2s_filter_packet
* c2s_presence_in
* c2s_remote_hook
* c2s_stream_features
* can_access_identity
* can_access_room
* caps_recognised
* check_bl_c2s
* custom_new_hook
* disco_info
* disco_local_features
* disco_local_identity
Expand All @@ -233,19 +229,22 @@ This is the perfect place to plug in custom security control.
* disco_sm_identity
* disco_sm_items
* does_user_exist
* ejabberd_ctl_process
* extend_inbox_result
* failed_to_store_message
* filter_local_packet
* filter_packet
* filter_pep_recipient
* filter_room_packet
* filter_unacknowledged_messages
* find_s2s_bridge
* forbidden_session_hook
* foreign_event
* forget_room
* get_key
* get_mam_muc_gdpr_data
* get_mam_pm_gdpr_data
* get_pep_recipients
* get_personal_data
* get_room_affiliations
* inbox_unread_count
* invitation_sent
* is_muc_room_owner
Expand All @@ -254,19 +253,24 @@ This is the perfect place to plug in custom security control.
* mam_archive_id
* mam_archive_message
* mam_archive_size
* mam_archive_sync
* mam_flush_messages
* mam_get_behaviour
* mam_get_prefs
* mam_lookup_messages
* mam_muc_archive_id
* mam_muc_archive_message
* mam_muc_archive_size
* mam_muc_archive_sync
* mam_muc_flush_messages
* mam_muc_get_behaviour
* mam_muc_get_prefs
* mam_muc_lookup_messages
* mam_muc_remove_archive
* mam_muc_retraction
* mam_muc_set_prefs
* mam_remove_archive
* mam_retraction
* mam_set_prefs
* mod_global_distrib_known_recipient
* mod_global_distrib_unknown_recipient
Expand All @@ -279,18 +283,20 @@ This is the perfect place to plug in custom security control.
* privacy_get_user_list
* privacy_iq_get
* privacy_iq_set
* privacy_list_push
* privacy_updated_list
* pubsub_create_node
* pubsub_delete_node
* pubsub_publish_item
* push_notifications
* register_command
* register_subhost
* register_user
* remove_domain
* remove_user
* reroute_unacked_messages
* resend_offline_messages_hook
* rest_user_send_packet
* room_exists
* room_new_affiliations
* room_packet
* roster_get
* roster_get_jid_info
Expand All @@ -311,22 +317,33 @@ This is the perfect place to plug in custom security control.
* session_opening_allowed_for_user
* set_presence_hook
* set_vcard
* sm_broadcast
* sm_filter_offline_message
* sm_register_connection_hook
* sm_remove_connection_hook
* unacknowledged_message
* unregister_command
* unregister_subhost
* unset_presence_hook
* update_inbox_for_muc
* user_available_hook
* user_open_session
* user_ping_response
* user_receive_iq
* user_receive_message
* user_receive_packet
* user_receive_presence
* user_receive_xmlel
* user_send_iq
* user_send_message
* user_send_packet
* user_sent_keep_alive
* user_send_presence
* user_send_xmlel
* user_socket_closed
* user_socket_error
* user_stop_request
* user_terminate
* vcard_set
* xmpp_bounce_message
* xmpp_presend_element
* xmpp_send_element
* xmpp_stanza_dropped

Expand Down

0 comments on commit 245c279

Please sign in to comment.