SMART icon indicating copy to clipboard operation
SMART copied to clipboard

WIP: Timeout to leave_coding_page

Open schittarath3-rti opened this issue 3 years ago • 5 comments

Adds timeout mechanism for coders and admins who have not coded or performed an admin-specific action after five minutes.

  • The server runs a celery task every five minutes to check the following
    • For admins, the timedelta between the time of checking and the last_action field in AdminProgress is <5min
      • last_action is updated every time an admin performs an action on an admin tab
    • For coders and admins who have timed out, the timedelta between the time of checking and the assigned_timestamp field in AssignedData is <5min
  • Clients runs an ajax GET every minute to check its status and performs the following actions
    • For admins that had access, but have now timed out of admin access, the admin tabs will become unavailable, but will still retain coding access. This is done in case the admin is just coding and we do not want them to timeout from coding access.
    • Admins who did not have access will have the same behavior as coders
    • Timed out coders will have a prompt to refresh the page to re-retrieve cards

Notes: ~~One issue I ran into is that the get_card_deck and enter_coding_page api calls are nondeterministic. In the case where get_card_deck is called before enter_coding_page, data is assigned, but then unassigned in enter_coding_page. There is a commit that fixes it here, but I am not sure if that is a problem in npsas_main~~

schittarath3-rti avatar Jul 27 '22 18:07 schittarath3-rti

leaving note here: could use something like SWR for the client-side request?

dsteedRTI avatar Aug 09 '22 18:08 dsteedRTI

Problem: Continuous polling may take up too many resources. Client might not update as soon as the server time outs the client.

Django channels (web sockets) Docs

  • Description: * Creates a channel layer that allow multiple instances (ie users) to talk to each other
    • Process:
      • Server creates a group for each active project
        • Groups only allow broadcasting to all clients in that group, can’t enumerate over clients in group. We may need to create our own group data structure to handle when we want to unicast vs broadcast
      • Client opens a web socket to server, server adds client to channel group
      • Django still runs a celery timeout task to timeout admins and coders (more on this later)
      • On a coder timeout,
        • Purge assigned data from coder
        • If window is still active (web socket is still open):
          • Unicast a message on socket to interrupt coding if window is active
          • Remove cards with message saying “Need to refresh…”
        • If not (WS connection closed by exiting page or browser close),
          • Nothing happens client side
      • On admin timeout,
        • Purge AdminProgress from admin
        • If window is still active:
          • Unicast a message on socket to interrupt AdminProgress if window is active
          • Remove admin cards with message saying “Timeout, Need to refresh…”
          • Broadcast message on socket to all potential admins tell admins to refresh to POTENTIALLY get admin privileges

schittarath3-rti avatar Aug 10 '22 19:08 schittarath3-rti

Problem: Celery is not implemented in prod

  • Admin workarounds:
    • Potential no celery workaround 1: Only Admin API request for Admin 1

      • Admin 1 sends message saying that it is still active
      • Server updates last_action on every action (api request from that admin, browser activity from admin)
      • If Admin 2 wants access and last_action time delta is large enough, give access to Admin 2
    • Potential no celery workaround 2: on-demand admin access

      • Depends on being able to immediately tell admin 1 that their access has been revoked, i.e.
        • SWR
        • Django channels
        • Rapid polling (seconds between requests)
      • When Admin 2 tries to enter admin tab, Admin 2 sends a message to server asking for privileges
      • Server handles it in three cases:
        • If Admin 1 has not timed out, block access and serve page saying to refresh later
        • If Admin 1 has timed out,
          • Send unicast to Admin 1 with message saying session timed out
          • Immediately give access to Admin 2
          • Send broadcast to all other Admin 2 with message saying to refresh
        • If there is no admin, give access
  • Coder workarounds:
    • See PR #207

schittarath3-rti avatar Aug 10 '22 19:08 schittarath3-rti

We might also be able to replace celery with a django-friendly alternative if we cannot use celery in prod: https://github.com/rajasimon/beatserver. This django app relies on django channels, but allows us to schedule tasks periodically, like celery is doing in this PR.

schittarath3-rti avatar Aug 10 '22 19:08 schittarath3-rti

Potential no celery workaround 1: Only Admin API request for Admin 1

Admin 1 sends message saying that it is still active Server updates last_action on every action (api request from that admin, browser activity from admin) If Admin 2 wants access and last_action time delta is large enough, give access to Admin 2

If we go with option 1, and remove Admin 1 from the admin assigned table when Admin 2 needs things and Admin 1 has been away for long enough. Then what happens to admin 1 if they still have the table open and try to label something in the admin table? I think that's the question. They probably would be able to interact one time before the table would refresh and let them know they were kicked out (we need to check this).

I think a simple solution to avoid multiple admin potentially labeling the same item is just add some checks to the admin api calls like label_admin_label so that if an admin has been kicked out, and they try and label something, the label doesn't complete.

AstridKery avatar Aug 11 '22 16:08 AstridKery