Join GitHub today
Minutely Scheduled Tasks #304
Right now the Scheduler in NZBGet supports basic features such as:
This is great! But for the script I recently created to scan for NZB-Files, it'd be cool if it was feasible to scan minutely or even just every 2 minutes using the built in NZBGet scheduler. Maybe support something as basic as this (i'm not sure the level of effort off hand):
Of course, i wouldn't complain if you got fancy and supported cron like commands such as:
As it is right now, it's almost easier to just use the dirwatch in a cron (no help for Windows users) with:
Maybe my script is the only use case right now making this request unnecessary? Maybe there are more tools/scripts that would benefit from it?
I guess I can do that. However the thing is the scheduler in nzbget isn't as sophisticated as cron. The support for
So for example when you use
If we use that for minutes it will be easy to define minutely tasks resulting in 3600 task objects. All of them checked every second. Sounds not optimal.
It's surely possible to rewrite the scheduler to be more advanced to not require creating of separate tasks for each time point but that would be certainly more work.
Another concern is a possible performance impact of starting python scripts that often. A live example: my primary download machine is a Linux SAT receiver with CPU MIPS 400 MHz dual core. During download it eats the whole CPU (and still can't saturate my Internet link). When testing FakeDetector script I've found a problem: due to high load of CPU the startup time of the script was about 50 seconds (before the first line of the script was executed). Even on idle CPU the system requires several seconds to start python.
Yes, that's a slow machine. But even on much better machines it may become a problem when the CPU is fully utilised.
Considering all of this I think a better approach could be to start the script once and keep it running. The script should then organise a run loop with sleep intervals.
When to start the script?
The user could configure the script to run (for example) every 15 minutes. On start the script should check the existence of another running instance. That can be achieved with lock-files.
The scheduler interval of 15 minutes means a delay between nzbget starts and the script starts. To avoid this delay we could extend the scheduler with ability to start scripts when the program starts. For example let's say the value
Could be probably useful for other things too.
I like your alternative idea!
Do you think you could provide the PID of the NZBGet instance so that the python script can die quietly if NZBGet does? Just a way of still keeping an artificial Parent/Child relationship? This is especially the case if someone sends a reload signal to NZBGet, I'd want to know that too because maybe i shouldn't be running in memory anymore, or i have new paths to scan. A reload should effectively kill my forked process until the next Scheduled interval is reached (but i can do that myself knowing the PID or getting a SIGHUP of my own). Perhaps i should send a signal back to you of my PID for you to manage?
I presume the PID changes on a reload anyway so this would just work if you could pass that info along.
On a side note; don't knock yourself on the current architecture; as basic as it is; it works great. So all is good! I was just proposing options! :)
added a commit
Nov 15, 2016
added a commit
Nov 15, 2016
Script startup on program startup
Graceful script shutdown
If a script is running when the program must shutdown, the script receives signal SIGINT (SIGBREAK aka CTRL+BREAK on Windows) and has 10 seconds to gracefully terminate until it is killed.
Example script which handles shutdown signal:
#!/usr/bin/env python ### NZBGET SCHEDULER SCRIPT # This script hangs in a loop but can be gracefully terminated on program shutdown. # # NOTE: This script requires Python to be installed on your system. import os import sys import time import signal interrupted = False def signal_handler(signum , address): print "Received terminate signal" global interrupted interrupted = True if os.name == 'nt': signal.signal(signal.SIGBREAK, signal_handler) else: signal.signal(signal.SIGINT, signal_handler) a = 1 while not interrupted: try: a += 1 print('[INFO] ' + str(a)) sys.stdout.flush() time.sleep(1) except Exception as e: print('[ERROR] Exception: %s' % e) print('[INFO] Exiting') sys.stdout.flush()
You're seriously working way to hard over there HugBug ;). What I might do is adopt this into my pynzbget wrapper so that anyone can just have the signal handling functionality who need it. I'll start with the dirwatch script (discussed earlier) as my first test.
Thanks for all your great work!