Kord-Extensions/kord-extensions

Locking state between check and action

Closed this issue · 4 comments

Summary

Concurrency and race conditions are annoying, - so are locks, but sometimes it's needed to guarantee consistency.
In some situation you want to make precondition state checks in the check DSL and follow up on that in the action DSL, which modifies that state.
But what if two checks are handled concurrently, both are passing and we move both into an action, where only one should have passed?
Well you can lock the check.
That reduces the probability of such a case, but it doesn't eliminate it, because there could still run another check while the action is in progress.

TL;DR:
Check and Action should have the option for a shared lock, so no check nor action can be executed while something is operating on the scope of this lock.

Problem: How to define the scope of a lock (for components)

  • Full Message
  • One Component

Current Behaviour

No locking mechanism is implemented

Preferred Behaviour

A configurable lock / consistency gurantee between checks and actions.

As of the latest push, the following has been added to all (actionable) component and command builders:

  • lockable boolean, set this to true to lock before command execution and unlock after
  • mutex property, which will be filled automatically if you don't provide your own mutex, but you can supply one for more advanced locking purposes

The mutex covers the entire command execution, which means it'll cover checks, the initial response/ack, and the command action itself. There is currently no special handling for interaction-based commands, which means they'll fail if the mutex doesn't unlock quickly enough. If that turns out to be an issue, we can look at changing that somehow.

Let me know how you get on with this!

This appears to work for me!
But I still see warns about "unrecognized buttons" in the log, when a button was deleted on KordEx but clicked while the discord edit is pending. This could be a seperate issue though.

As long as that has no negative side effects, you may well be stuck with that. Locking is something that doesn't really fit well into a coroutine model, so you're gonna have compromises.

The scope of this ticket is resolved. Thank you!