Make the scheduler work with many replicas

I just realized that if I use multiple replicas in a project, then when using Schedule actions, they will be triggered multiple times, according to the number of the containers.

I assume it can be handled if it is gonna check the number of current container, using ENV variables, and then start the action only for the first container.

But how can I get this number?

This is not a solution, just something for you to check:

1 Like

Thank you!

That’s indeed a useful start for digging into this question. But I am still not experienced in Docker stuff, so I’m afraid I am not gonna investigate it yet.

I was curious if someone already has dealt with similar problem and may have ready solution.

At the moment it seems like if using several replicas in Wappler, it disables the ability to use Scheduled actions (except when the user is capable of tweaking this issue themself).

As a temporary solution I just ran a special server with 1 replica, that will start scheduled actions, that would trigger regular actions on the main server. Ugly and risky, but will do a job for a while. :sweat_smile:

1 Like

Hey Nick,

I added replicas today, and quickly noticed this scheduler issue as well. Did you find a good solution you care to share?

You can get the containerID in a docker container with a script like:

const fs = require('fs');

async function getContainerId() {
  const cgroup = fs.readFileSync('/proc/self/cgroup', 'utf8');
  const [, , containerId] = cgroup.trim().split(':perf_event:');
  await fs.promises.writeFile('/app/container-id', containerId);
  return containerId;
}

This would write it to a file as well but you could export it to the ENV, too.

1 Like

Thanks Tobias,

I’ll have a look at that…I’d certainly prefer to continue to use the scheduler from the wappler ui instead of the external crons I just setup to get around this.

Much appreciated!

No worries. I‘m not using Wappler for deployment but a GL CI/CD pipeline. In case you use CI/CD as well you could export the ENV variable during the build process or if you use a custom dockerfile then you could add it there. But the script option to run it during application runtime is better imo.

And for anybody who wants to use the script above you can use this Trigger An API Call When The Server Restarts to run in only on application start.

Hi, Ken!
Unfortunately I didn’t. So I stuck to a simple solution with the additional Wappler project on a different server that works as a scheduler. I don’t like this much, but it does the job.

1 Like

I think the node scheduler should schedule jobs on every application replica by design and not only on one instance if you have multiple instances of your application.

If you need a job to run only once, it should be stored in persistent storage outside the application itself.

Something like Bull and Redis can store jobs outside of the application.
The next major release of the bull extension will allow you to add scheduled jobs, which will only be processed once, no matter how many replicas you have. So this might solve this issue.

CleanShot 2023-05-14 at 17.35.25

4 Likes

I agree with Tobias that the scheduler should run on every application instance. There are many jobs like cleanup that need to be run on every instance. When you have some job that isn’t instance specific you could use something like the bull extension or you keep track of a queue yourself in a database, the advantage is also that you distribute the work over all instances instead of having a single server doing the work.

2 Likes

@patrick @tbvgl Thank you for your input! Your points sound reasonable and I think you are right from the point of best practices of web development.

But I still feel like this area is not obvious from a nocode dev perspective. Because I think in most cases for not experienced Wappler users it is expected that the scheduled actions always work only once.

I understand that there is no simple solution, but maybe it is something to think about.
Maybe in terms of UI there should be two subfolders in Schedule: one for actions that will run for every instance and one for actions that will run only once.

The next major release of the bull extension will allow you to add scheduled jobs, which will only be processed once

That’s amazing news, thank you! I’ll be waiting for an update then.

Hey @nickneustroev the new version is live here:

It’s very easy to install npm i wappler-bull-queues. When installed create a queue and make sure to tick the autostart box so that it automatically starts when your application restarts:

CleanShot 2023-05-19 at 19.58.41

and then add a job and choose either a cron interval:

or a regular interval:

1 Like

That’s awesome! Many thanks, Tobias