Timers and timer triggers

Does anyone know if there is a way to use timers to trigger itself to restart, or to trigger a list to rotate items? Here is what I’m trying to do and I have been able to do this in Glide but I would like to switch to Adalo. I have a list of people that submit themselves to the list manually via the app (this is simple and I figured this part out). The timer runs in 30 minute intervals regardless of who is looking at it. Its based on current time. So whoever is at the top of the list has 30 minutes to complete tasks, when time is up they are moved to bottom and the next person is givena chance at the same tasks. If they complete the tasks before the timer they can remove themselves from the list when that happens the 2nd becomes first and timer restarts.

Hi @Drearystate,

After some thinking, this tasks seems not to be an easy one. The main problem I see here is that all user “rotation” should be done on a server side with a single “rotation engine”.

At first I thought about some kind of app-driven events (like when user opens the app and the time has finished - DB update action is called), but big potential problem with this approach will be the potential of concurrent actions from different users (imagine 2 users opening the app simultaneously).

As Adalo doesn’t have internal scheduling / cron system at the moment, it might be worthwhile to investigate Zapier, Integromat or some other 3rd party service like EasyCron. Although their pricing is not very friendly…

So I can’t find an easy solution at the moment. May be someone other on the forum could help. @pfordmedia @Colin @karimoo @Devops what do you think?

Best regards, Victor.

Hi @Victor,
OK, I took the challenge and had to think about it for some time.
@Drearystate @Colin @Devops here is my idea how to get close to the scenario.

We need two tables/collections.

Registration
When the participants register, a record for the user is created in the Participant table with a timestamp (Current time) of registration.
The list is sorted ascending by registration time.

User starts the task


When the first user (here: Lisa) starts working, a record is created for the active user with
Start Time = Current Time
End Time = Current Time + Task Duration (30 minutes)
image

For details on time calculations, see Activate the purchasing services according to the opening hours: morning and afternoon and Help : StarTIME +60 = funny Endtime 🤔

The flag Active for the current user is set to TRUE

User ends the task


Independent if the user clicks a button or the session times out, the flag Active for the user ending the session is set to FALSE and a new registration with current time stamp is added at the end of the participant table.
The next participant taking over the task. The record for the participant on top of the list (lowest registration time stamp) is “moved” to the session table:

  1. Add new record for next user with
    Start Time = Current Time
    End Time = Current Time + Task Duration
    Active = TRUE
  2. Delete record from participant list

What timing mechanism can we use?
So far the concept.
But, as @Victor pointed out: We don’t have a scheduling / cron system that runs on the server.
What we currently have is the Countdown component you can install from the Component Marketplace.

The downside of this is that the countdown runs on the device of the user.
The countdown starts when the screen that includes the component is opened.
On Click and at the end of the countdown we can add actions:
image
That would work to update the tables/collections as described above.
But:

How can we see the same timing when the counter runs on every device?

The only way for “synchronization” is to start the timer based on the start time of the taks and the elapsed time.

The duration of the countdown is defined in seconds.
For a 30 minutes task I would just use 1800 seconds when I can us a fixed value:
image

For the “synchronization” we need a calculated value:
image

This formula first calculates the difference between the Start Time stored in the Session table and the current time and transforms the decimal result (part of one day) into seconds by multiplying with 86400 (seconds per day). This calculated elapsed time in seconds is subtracted from the task duration of 1800 seconds. The formula also has to uses rounding as the Countdown component expects an integer. the +1 add the end is added to allow some “processing time”.
This is based on some testing I did with starting a second timer on a subsequent screen:

When the Start button is clicked the start and end time is stored in a collection.
The countdown on Screen 2 uses a fixed value of 1800 seconds.
The second countdown is started when ever the screen is launched and the countdown time is calculated using the formula from above.

First I have to mention that the countdown on the first screen runs down independent from my navigation steps. Whatever is calculated for the timer on the second screen, the first timer has the “truth” for this device/user.

As you (hopefully) can see in the GIF:
The synchronization is not perfect because of the rounding and processing time (pulling the start time from the server, starting the countdown on the device, etc.).
But depending on the scenario this can be good enough.
Note that starting the timer on the second screen with a calculated value is the same scenario as starting the timer with another login on another device. With some variance of +/- 1 second.

@Drearystate So it depends on your use case, if the view on the countdown for different users is good enough. If you are thinking of a multi-user gaming scenario probably not. For a “gamified” app to engage you learners it will do.

There are some more things to think about. For example:
How to handle, if the active user stops working on the task without triggering the update actions (just stops working, network issues, whatever)?
There is no job running on the server to check this and adjust the state. The only option would be to have the next in line user trigger the updates.
Or if you think about extending the tables to have statistics like top lists, average time to solve the task:
Keep in mind that there is also no easy way to do mass updates for multiple records in a table. That is why I tried to handle just single records.

2 Likes

@karimoo amazing! :clap: :clap: :clap: :clap:

Do you think there will be no “race condition” with countdown timer? I wonder what would happen if there will be for example 100 users logged-in simultaneously.

Best,
Victor.

2 Likes

Thank you @Victor.
In this scenario we have a task duration of 30min. If there are 100 users on the list for the same task the last one would have to wait up to 2 days before being able to start :slight_smile:
Even if all 100 want to know the status of the running session this would mean 100 selects on the same table/collection. That shouldn’t be too challenging :slight_smile:

1 Like