My web app supports multiple users, for one particular task, it can be completed by any one of several users, that is, I don’t want multiple users to work on the same task at the same time, thus, the need to “lock” the task when a user starts to work on it. No matter if this user has completed the task or not, when he logs out or leaves his/her computer an extended period of time, say, 2 hours, (app session timeout is 4 hours), I’d like to release the “lock”.
So, we know we need to release the "lock in any of the following situations:
- user logout
- for the extended period of inactivity, is there a convenient way to find out?
- the user closes the browser tab or the browser, then how do we detect that (onunload & onbeforeunload? ) ?
- any other situation that the user is no longer working on the app?
User logout is pretty easy… when the user logs out then check if that user has any locked tasks and unlock them
For inactivity it would depend on how you’re currently handling session management. In my session management each user has a
lastActionAt datetime variable (that is persisted - to the database, or in my case, the cache). Normally this is used in, say,
onRequestStart(), to check if the user has timed out (and thus force a new login). However, one could set-up a scheduled task that polls user sessions
lastActionAt variable and if it exceeds X minutes, or the session no longer exists, then check if that user (or in the case of a session no longer existing, any not logged in user) has any locked tasks, and if so, unlock them.
3 and 4 would use the same polling as 2, so if they close their browser window, lose their internet connection, or some (any) other condition which no longer updates their session’s
lastActionAt variable, the task would still be unlocked after X minutes of inactivity.
A good primer on rolling your own session management (where this technique could be applied) can be found at https://cfdocs.org/security-session-management
My concern for implementing 2), 3), 4) is if the overhead justifies the need, probably it’s more a business decision than a technical one.
Yeah, if you have thousands of locked tasks at any given time then the overhead there might be too steep.
An alternative would be to check if the task is unlockable at the point where another user wants to open it. Then you can check if the previous user is still logged in, if they are then check the
lastActionAt and if it’s past the timeout then unlock. And, if the user is not logged in, then unlock. More of a just-in-time solution that eliminates polling overhead.
The con here is if you’re displaying lock status to users then they won’t know if it’s unlockable until they try. But then a ‘Sorry, this task is locked by Y user’ kind of message would suffice. It’d be horrible UI design lol, but better than nothing, perhaps?
Otherwise, you’re pretty well stuck with polling unless someone else has better ideas