Closed wojnilowicz closed 4 months ago
You're welcome. Indeed, this is a suggestion. I use it.
ActivityWatch manages its modules, if you run them through aw-qt. It also has a systemd service at https://github.com/ActivityWatch/aw-server-rust/blob/82345cfc5371c673a9bc2b5284530ae8c180153d/aw-server.service that lets you start aw-server, but then its modules don't start. This MR is for aw-awatcher to start just like aw-server. No need to start aw-qt.
The issue with delay is so that if aw-server doesn't initialize fully then aw-awatcher goes dead, but systemd doesn't know that. If you can fix that somehow (either by failing aw-awatcher or idling for aw-server) then it would be even a better solution.
BTW, I believe the issues you pointed doesn't help me. I don't use bundled version and I use you latest watcher and still have to be careful when to start your watcher.
The issue with delay is so that if aw-server doesn't initialize fully then aw-awatcher goes dead, but systemd doesn't know that.
There are 3 reconnection attempts with 1 second interval, doesn't this work for you? Maybe, 3 attempts/2 seconds waiting is not enough?
It has After=aw-server.service
, so I would expect it to work, especially after the delay.
either by failing aw-awatcher
Doesn't aw-awatcher fail the way which is recognized by systemd?
The issue with delay is so that if aw-server doesn't initialize fully then aw-awatcher goes dead, but systemd doesn't know that.
There are 3 reconnection attempts with 1 second interval, doesn't this work for you? Maybe, 3 attempts/2 seconds waiting is not enough?
Certainly not on my old machine. It's far too less. I also have a newer and quite fast machine, but I wouldn't bet that 3 times 1 s is enough for it 🙂
It has
After=aw-server.service
, so I would expect it to work, especially after the delay.
After=aw-server.service
is not helpful here as it only marks that the aw-server executable has been launched. I believe your awatcher expects to communicate with it to not fail, and for this aw-server needs a bit more time, hence the delay of 100 seconds. My newer machine can go way below these 100 seconds, so this solution is not perfect, so you could come up with something more robust if you want to invest time in it.
either by failing aw-awatcher
Doesn't aw-awatcher fail the way which is recognized by systemd?
I'm not an expert on this but replacing the delay with
Restart=on-failure
RestartSec=30
under the service tag doesn't help, so I concluded that it doesn't actually report failing. Maybe the return code is still zero.
under the service tag doesn't help, so I concluded that it doesn't actually report failing. Maybe the return code is still zero.
Just checked, the return code is ok if you have this error:
Error: Failed to create bucket aw-watcher-afk_demi-desktop-linux
Caused by:
0: error sending request for url (http://127.0.0.1:5600//api/0/buckets/aw-watcher-afk_demi-desktop-linux): error trying to connect: tcp connect error: Connection refused (os error 111)
1: error trying to connect: tcp connect error: Connection refused (os error 111)
2: tcp connect error: Connection refused (os error 111)
3: Connection refused (os error 111)
$ echo $?
1
Yes, maybe I should experiment a bit more with this. Thanks for the error codes listing. I'm surprised that an error code could be 0. Shouldn't that be reserved for "everything's ok"?
I'm surprised that an error code could be 0. Shouldn't that be reserved for "everything's ok"?
I'm not sure I understand, the error code for awatcher is 1 when the aforementioned exception happens as echo $?
shows in the snippet. Otherwise, 0 is returned on a regular exit, I've just checked.
Ok, I did no try it yet, so maybe I don't quite understand what "0: error sending request for url [...]" means.
Here's what I'm using:
[Unit]
Requires=aw-server.service
After=aw-server.service
[Service]
Type=simple
# Verbosity level: -v for warnings, -vv for info, -vvv for debug, -vvvv for trace
ExecStart=/bin/bash -c 'aw-awatcher --version && aw-awatcher -vvvv'
Restart=always
RestartSec=60
Nice=18
IOSchedulingPriority=6
# Was not able to test this on a system where it has an effect:
# CPUQuota=10%
[Install]
WantedBy=default.target
and
[Unit]
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'aw-server'
Restart=on-failure
RestartSec=60
Nice=18
IOSchedulingPriority=6
# Was not able to test this on a system where it has an effect:
# CPUQuota=10%
[Install]
WantedBy=default.target
Not sure, but maybe setting Nice would be something to consider?
Thanks for sharing, but I'm not sure "nice" is a robust solution here.
Now I'm just leaning more toward that this should be fixed on ActivityWatch side through something called forking as seen at https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html which will assure that aw-server is initialized fully before aw-aw_watcher starts.
Then here the systemd service could be minimal.
I used sd-notify in aw-server-rust to inform systemd exactly when the server is up and running and only then start awatcher, but that didn't help during boot, so it's not about non-existent communication with aw-server-rust.
What I found is that without ExecStartPre=/bin/sleep 100
awatcher starts and immediately exits successfully. I suspect that in my case it's because kwin_x11 is not yet initialized. ExecStartPre=/bin/sleep 100
adds enough time for it to start. That's not robust, because the time it has to wait depends on the machine it runs.
The new version of the service should be robust on every system. It sleeps for 5 seconds after aw-server.service or graphical-session.target (that's where kwin_x11 starts) starts. If it will not find KDE or GNOME, it'll exit successfully, but will try to restart itself after 5 s then after 10 s and then after every 15 s and will finally give up after 2 minutes.
Could you accept that PR?
Thank you for your updated config. It looks more robust and shareable, but it requires aw-server.service
too. I've merged it anyway (to another folder, "watcher" is a local crate), and mentioned it in readme.
Thank you for your suggestion, doesn't ActivityWatch manage the modules and run the modules itself? I have added a similar functionality myself to the bundled version which works almost identically to the original distribution of ActivityWatch (particularly, Qt-based tray icon app).
Or is it about the delays? If some environment requires a timeout, I think it may be considered in the code to facilitate the usage for everyone, for example, I added delays and more attempts for #8 and #11