-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Valkey triggers proposal #9
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Ran Shidlansik <[email protected]>
Signed-off-by: Ran Shidlansik <[email protected]>
Signed-off-by: Ran Shidlansik <[email protected]>
"total_duration" - the aggregated total duration time this trigger run | ||
|
||
*** Open question *** | ||
should `CONFIG RESETSTAT` also reset the triggers statistics, or should that only be done when functions lib is reloaded? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they should be reset at the same time that function-statistics are reset.
### Debug mechanism | ||
|
||
While Valkey functions and scripts are executed as part of the FCALL/EVAL calls, it is thus possible to report the errors back to the calling client. | ||
Triggers, however, are silently executing which makes it hard for the user to understand why the trigger did not work and what errors occurred during execution of the trigger. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this context I take the user to be a developer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
1. All error msgs will be intercepted as deferred errors (much like modules do). | ||
2. After trigger completes run, in case errors were issues, it will update the stats with the num,ber of errors. | ||
3. The trigger will report the errors to a dedicated channel in the following structure: | ||
`__triggers@errors__:<trigger-name>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't the log sufficient?
Based on how errors are counted, it seems that a triggered function might attempt to report an error that should be delivered to the client. This suggests that the message will not normally be delivered. What would be delivered?
I have not worked with LUA or EVAL in the past. It seems likely that the answers to some of my questions would be obvious if I had. Please point me at any reading you think would help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the trigger execution is hidden from the user we cannot just return it as an error.
For the case when the trigger is issued based on internal events (eg evictions) there is no request context to issue the error to.
For case were the event was issued as part of the complex command flow (eg script or transaction),
we have 2 options to consider trigger execution:
- without breaking the action atomicity (in which case the trigger will be executed AFTER the command was executed) in which case the response to the command was already sent or written to the COB, so not much point or ability to return it to the client.
- we can execute the trigger as soon as the event is reported, practically breaking the atomicity and in this case I agree there is a problem we need to consider how to handle trigger failure, since it potentially already changed the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, let me say on on the record of conceptually likely stored procedures and triggers. I also find Lua to be fun and useful. I'm not sold on the combination described here though.
Second, While I personally like Lua, that being the only engine limits it for a lot of users.
Third, the sections about atomicity, recursive, and ACLs in this doc reveal how tricky it is to get this to work in the context of Valkey. The complexity in each of these makes this tricky to navigate for users in balancing security, stability, and data guarantees: someone attempting to use this is very likely to get it wrong and unwittingly sacrifice something they didn't intend.
Might the goals of triggers be accomplished by some other means: maybe a persistent keyspace notification mechanism? Perhaps hook interface to another runtime that would prove to be more flexible? There are some good inspirations for these in other NoSQL databases that might work here.
As stated before, a trigger is basically a specific engine function. | ||
The function synopsis will be identical for all triggers which will get the following parameters: | ||
|
||
**a. key -** the key for which the event was triggered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I'm a little confused here. It appears that you're using something different from the keyspace/keyevent notification format? Why not the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The event description is identical to the channel name used to report the keyspace events.
### Atomicity and triggers | ||
|
||
All keyspace events are triggered immediately after the operation which triggered them. If we allow the triggers to be executed when the keyspace event has been triggered, | ||
It means allowing a write call performed in the middle of operating another command. Another (technical) issue is related to nested scripts. Currently there is a [protection](https://github.com/valkey-io/valkey/blame/unstable/src/script_lua.c#L891) in Valkey code preventing to execute lua script from a scripts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this work with [WATCH
]MUTLI
/EXEC
? Does it interrupt a transaction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping to discuss this section. IMO we should NOT break atomicity with triggers, although this was the way I implemented the PoC. allowing triggers during scripts and transactions can indeed lead to much confusion but alternatively, queuing them and allow them to be executed after the transaction can be problematic since the trigger context might be lagging behind the data. I agree this part is the most problematic.
Since Redis triggers are built on keyspace events, the DB scope will be the same as the keyspace event was issued on. | ||
|
||
#### ACL User scope | ||
By default the scope of the user will by the superuser which will not be limited by any authentication restrictions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should default to least privilege rather than greatest.
the name of the ACL user to attach to the trigger run context. | ||
|
||
### New Commands | ||
1. `CLIENT TRIGGERS [ON|OFF]` new subcommand. Sometimes it will be required to mute trigger execution in some context (say administrative fix to the dataset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All or nothing? What if someone wanted to disable some triggers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can extend this in the future if we want. the point of this ability is that the developer/admin wants to access the data and have no interference of triggers while doing so.
Triggers.md
Outdated
|
||
### Triggers as part of function libraries | ||
Valkey triggers will be implemented as an extension of the Valkey [Function Libraries](https://valkey.io/topics/functions-intro/) . | ||
A trigger is basically a Valkey function which will be called when some specific keyspace event was issued. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are triggers limited only to keyspace events? Could you also trigger on an event through some arbitrary channel/pattern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SO I thought of the keyspace events since they are already defined and known to users, so I think it would make it easier for users to adopt. I am open to other suggestions.
|
||
Here is an example library code to schedule tasks to be executed after/every several seconds | ||
|
||
![image](https://user-images.githubusercontent.com/88133677/225652613-aa85beee-05f1-4c5e-abe7-1d334b0e882f.png) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes please. The use of images is also inaccessible.
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
|
thank you @stockholmux. Can you tell me what in the combination blocks you?
While I might agree, LUA is still a very efficient engine. Also I find this out of scope of this discussion. in case we add more engines the support for the triggers will still be there.
I agree about atomicity. this is a challenge but lets be honest - it is not kids who are playing with Valkey - it is usually developers that can be thought to consider the actions they are placing. the execution will still be serialized and the developer can just as well shoot himself in the lag while communicating several clients to the same Valkey server.
Sure It can. We can introduce timers which would help in many of the described cases. |
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Madelyn Olson <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
Co-authored-by: Daniel House @ Seeking Opportunities <[email protected]> Signed-off-by: ranshid <[email protected]>
@stockholmux @daniel-house I would like to thank you for spending the time reviewing this! |
This is a proposal to introduce Valkey Triggers.
Valkey triggers are persistent procedures which are executed in response to some keyspace event.
Today Valkey keyspace Notifications offer the ability to publish events to dedicated pub/sub channels.
Valkey triggers add the ability to place extending logic on such keyspace events and to localize actions on the server side reducing the need to monitor and react to events on the application side.
We propose to extend the existing Valkey Functions with the ability to define trigger function call on specific keyspace event.
As being integrated in the Valkey Functions infrastructure, Triggers are persisted as part of the user data.