Systemd Timers possible to use in PHP Symfony App

Visualise craigslist, it has a page of Ads listed by most recent at top.
The Ad at the top of the list will drop down the list as new Ads are added.

If we give users the option to 'Bump Ad to top of listing every hour ‘for the next 3 hours’ (user can select how many hours)

The following should occur:

User1 Bump Ad starting now Wed 13:52 and selects 3 hours
We expect the Ad to be at the top of the list at these times:
14:52
15:52
16:52

If there is another user who also Bump Ad at a different time lets use 14:23
and also used 3 hours we expect user2 Ad to be at the top of the list at these times:
15:23
16:23
17:23

If the systemd timer is configured with the following:

[Timer]
OnActiveSec=1hr
OnUnitActiveSec=1hr

*(OnActiveSec=defines exactly one wakeup, after you issue “systemctl start foo.timer”. It is not repeated then, it’s a singular event)

*(OnUnitActiveSec=multiple, repetitive arguments, need to be combined with OnUnitActiveSec=)

*Source https://github.com/systemd/systemd/issues/4572#issuecomment-260014156

If Timer is Activated at 12:00 it will create a time offset:
User1 by 52 mins
User2 by 23 mins

This would result in each users Ad being Posted early or late since they are both relative to the Timers’
first activation time which apparently is global in this scenario.

Ideally each User Bump Ad Time needs to be unique and have an individual timer as Activation reference for repeated hourly events so that the listing page
and the Posted time is exactly the time the user clicked the Bump Ad button, and be updated exactly 1 hour after that time for how ever many times later.

Considering if the web app has 5000 users with 5 Ads each, it obviously it is not practical to have 25,000 unique timers for each Ad.

So, can a single systemd timer be used and configured to allow each Ad to be Bumped with it’s own activation time and thus its repeated Bump time 1 hour after?

The unit executes a bash script:
#!/bin/bash
curl https://foo.com/bump-ad-by-cron

to which received is:
{“msg”:“successfully bump-ad by cron”}

Maybe this is not even possible with systemd, maybe a different approach needs to be made in PHP, not sure, but some ideas with systemd would be a start.
I could install cronie, not sure if cron is capable of the requirement.

Very much like this forum, if users had account function to repost their post to the top of the developer Discussion list starting now, every hour for 3 hours so other users see it at the top. My post time needs to be updated and unique and the same with another user if they also chose to have their post repost to the top, it would repost at their time of execution and repost exactly 1 hour after their initial time for 3 hours without delayed offsets.

bumpAd.sh

#!/bin/bash
curl https://foo.com/bump-ad-by-cron

===================================================

bumpAd.timer

[Unit]
Description=bumpAd

[Timer]
OnActiveSec=1hr
OnUnitActiveSec=1hr

[Install]
WantedBy=timers.target

===================================================

bumpAd.service

[Unit]
Description=bumpAd

[Service]
Type=oneshot
ExecStart=/usr/local/bin/bumpAd.sh

===================================================

I would not solve this with systemd timers because I would want my web application design to be self-contained and portable. With this design, you’re limited to systems with systemd running (e.g. no containers) if you had to redeploy your application you’d have to make sure to redistribute the script and systemd units in addition to the application code itself.

In other words, the application should probably handle this schedule. Assuming you agree the timer states aren’t critical data and can be lost in the event of a crash, this should be fairly easy to do in memory.

With that said, I’m sure you can make it work…for science!
systemd services can be templates that take an argument/parameter. This could be your “identifier” per-post or per-user. See: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Service%20Templates and https://www.freedesktop.org/software/systemd/man/systemd.unit.html

1 Like

Hi puneetse,

Thanks for reply.

I was asked to setup cron on the server, which would mean having to install cronie to support this.

So I kept in mind, another completely different topic regarding an issue with cronie in the past that was spewing millions of error lines in the logs. At that time it was advised to use systemd as a replacement for the ageing cron.

So I decided to use that advice and start by using systemd timer as the alternative, since I was advised the web app would nee the server to run cron anyway.

So maybe Symfony has its own built in scheduler for these type of tasks.

Hrm, interesting, how to determine if critical or not. I can say, each Bump Ad cost the user 1$, this is a paid for optional extra. I’m sure users would consider it critical…how to determine otherwise, unsure.

The comment was to make sure you’re thinking about a software resiliency and risk management strategy.

The requirements have to come from your customer :slight_smile: The architecture should shape to the requirements. And, sometimes you’ll find customers who were previously unwilling to change their requirements suddenly become flexible when the cost is accurately presented. :smirk:

For example, if you implemented this with systemd timers the way you have it now, if the system happened to crash the timer state would be lost. Is that ok? Maybe. Maybe not. Can it be easily solved (hint: yes) or is it going cost something (compromise elsewhere, additional complexity, money, etc)?

As with most things it’s ends up being a balance with context.

You can just write a simple program to do that. It enters an infinite loop where in each iteration it sleeps for 60mins then perform the operations.

This program can be launched in background with program name followed by an ampersand.

By and large, php and time-based events are a problem due to the asynchronous nature of php.

You’ll find that most php CMS systems have some sort of cron implementation and try and solve this problem within the CMS itself. This is more effcient than doing it from the outside, since there is a process overhead. Using systemd to handle hundreds of events isn’t efficient from a resource perspective.

I’d encourage you to explore existing solutions for cron-like timers in PHP. For instance, pm2 might be part of a good solution. Of course, you should check and see if the CMS has some sort of cron solution already built in. Wordpress has one, for instance, and I’ve seen many smaller systems embed a cron-like solution as well.

Personally, I would likely write a background task that handles all the events, and maybe provide some persistent storage so that a machine reboot does not affect anything. This could be something in any reasonable programming language assuming that interfacing with PHP is as simple as using curl or manipulating a SQL db.

1 Like

Do we have a bundle of this pm2 for Clear Linux?

I have installed Nodejs-basic, not sure if pm2 needs to be installed as a bundle?

I completely misspoke. pm2 can be installed with npm but isn’t for php, instead, it handles javascript based services. I haven’t found a solid one-stop solution for php just yet.