Add stored procedures and triggers#47
Merged
Merged
Conversation
Pull Request Test Coverage Report for Build 325Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
dumbbell
force-pushed
the
stored-procedures
branch
3 times, most recently
from
February 10, 2022 13:28
43a07f7 to
e6c3d4d
Compare
There are two parts in this patch:
First, **stored procedures**.
We leverage the `khepri_fun` framework used to extract anonymous
functions (used for transactions) to extract and store one as the
payload of a Khepri tree node. The function will be replicated on all
Khepri nodes in the cluster and therefore can be executed anywhere,
regardless of the availability of the initial module(s) the function was
extracted from.
To store a function, we introduce a new payload record:
Payload = #kpayload_sproc{sproc = fun() -> ... end}.
This payload record can be passed to `khepri_machine:put/3` and
higher-level functions in `khepri`.
To execute a stored procedure, there is a new `khepri_machine` public
API:
khepri_machine:run_sproc(StoredId, StoredProcPath, Args).
`StoredProcPath` is the path where the function was stored in the tree
and `Args` is a (possibly empty) list of terms, like one would pass to
`erlang:apply/2`.
Stored procedures may do whatever they want and have side effects,
unlike transaction functions. Stored procedures don't have direct access
to the tree and can't modify it directly, again unlike transaction
functions. However, they are free to use the Khepri API to update the
tree as any caller.
The return value of `khepri_machine:run_sproc/3` is the return value of
the stored procedure.
When a path is queried using e.g. `khepri_machine:get/2`, the node
properties map has a `sproc` member instead of a `data` one.
Second, **triggers**.
A trigger is a way to associate an event with a stored procedure: when
the event occurs, the stored procedure is executed.
This commit supports only one type of event: changes to the tree (the
database). Whenever a tree node is added, modified or deleted, the list
of triggers is evaluated to see if one or more are interested in this
event. If some are, their associated stored procedure is executed.
To register a new trigger, one first defines an event filter, stores a
procedure and finally registers the association between this event
filter and the stored procedure (i.e. the trigger):
EventFilter = #kevf_tree{path = PathPattern,
props = #{on_actions => [create, update]}},
khepri_machine:register_trigger(
StoredId, TriggerId, EventFilter, StoredProcPath).
An event filter is evaluted using:
* the `PathPattern` which can contains path conditions;
* the event's action, i.e. whether a node was created, updated or
removed.
The return value of the stored procedure is ignored when executed in the
context of a trigger.
See #16.
dumbbell
force-pushed
the
stored-procedures
branch
from
February 10, 2022 15:04
e6c3d4d to
0cb2501
Compare
dumbbell
marked this pull request as ready for review
February 10, 2022 15:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
There are two parts in this patch:
Stored procedures
We leverage the
khepri_funframework used to extract anonymous functions (used for transactions) to extract and store one as the payload of a Khepri tree node. The function will be replicated on all Khepri nodes in the cluster and therefore can be executed anywhere, regardless of the availability of the initial module(s) the function was extracted from.To store a function, we introduce a new payload record:
This payload record can be passed to
khepri_machine:put/3and higher-level functions inkhepri.To execute a stored procedure, there is a new
khepri_machinepublic API:StoredProcPathis the path where the function was stored in the tree andArgsis a (possibly empty) list of terms, like one would pass toerlang:apply/2.Stored procedures may do whatever they want and have side effects, unlike transaction functions. Stored procedures don't have direct access to the tree and can't modify it directly, again unlike transaction functions. However, they are free to use the Khepri API to update the tree as any caller.
The return value of
khepri_machine:run_sproc/3is the return value of the stored procedure.When a path is queried using e.g.
khepri_machine:get/2, the node properties map has asprocmember instead of adataone.Triggers
A trigger is a way to associate an event with a stored procedure: when the event occurs, the stored procedure is executed.
This commit supports only one type of event: changes to the tree (the database). Whenever a tree node is added, modified or deleted, the list of triggers is evaluated to see if one or more are interested in this event. If some are, their associated stored procedure is executed.
To register a new trigger, one first defines an event filter, stores a procedure and finally registers the association between this event filter and the stored procedure (i.e. the trigger):
An event filter is evaluted using:
PathPatternwhich can contains path conditions;removed.
The return value of the stored procedure is ignored when executed in the context of a trigger.
See #16.