service will run on a separate thread unless explicitly mentioned by the user to block it in main thread

This commit is contained in:
sankalp_j 2018-09-20 17:18:36 +05:30
parent 2ab6714040
commit c0b4aaf089
4 changed files with 55 additions and 30 deletions

View file

@ -10,8 +10,7 @@ Inspired by this blog [`here`](https://www.g-loaded.eu/2016/11/24/how-to-termina
pip install timeloop
```
## writing a job looks like this
## Writing jobs
```python
import time
@ -32,8 +31,28 @@ def sample_job_every_5s():
@tl.job(interval=timedelta(seconds=10))
def sample_job_every_10s():
print "10s job current time : {}".format(time.ctime())
```
## Start time loop in separate thread
By default timeloop starts in a separate thread.
Please do not forget to call ```tl.stop``` before exiting the program, Or else the jobs wont shut down gracefully.
```python
tl.start()
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
tl.stop()
break
```
## Start time loop in main thread
Doing this will automatically shut down the jobs gracefully when the program is killed, so no need to call ```tl.stop```
```python
tl.start(block=True)
```
## Author

View file

@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
setup(
name='timeloop',
version='1.0',
version='1.0.1',
packages=['timeloop'],
license = 'MIT',
description = 'An elegant way to run period tasks.',

View file

@ -16,33 +16,46 @@ class Timeloop():
logger.setLevel(logging.INFO)
self.logger = logger
def _add_task(self, func, interval, *args, **kwargs):
def _add_job(self, func, interval, *args, **kwargs):
j = Job(interval, func, *args, **kwargs)
self.jobs.append(j)
def _block_main_thread(self):
signal.signal(signal.SIGTERM, service_shutdown)
signal.signal(signal.SIGINT, service_shutdown)
while True:
try:
time.sleep(1)
except ServiceExit:
self.stop()
break
def _start_jobs(self, block):
for j in self.jobs:
j.daemon = not block
j.start()
self.logger.info("Registered job {}".format(j.execute))
def _stop_jobs(self):
for j in self.jobs:
self.logger.info("Stopping job {}".format(j.execute))
j.stop()
def job(self, interval):
def decorator(f):
self._add_task(f, interval)
self._add_job(f, interval)
return f
return decorator
def start(self):
try:
signal.signal(signal.SIGTERM, service_shutdown)
signal.signal(signal.SIGINT, service_shutdown)
def stop(self):
self._stop_jobs()
self.logger.info("Timeloop exited.")
self.logger.info("Starting Timeloop..")
for j in self.jobs:
self.logger.info("Registered task {}".format(j.execute))
j.start()
self.logger.info("Timeloop now started. Tasks will run based on the interval set")
def start(self, block=False):
self.logger.info("Starting Timeloop..")
self._start_jobs(block=block)
# block main thead
while True:
time.sleep(1)
except ServiceExit:
for j in self.jobs:
self.logger.info("Stopping task {}".format(j.execute))
j.stop()
self.logger.info("Timeloop exited.")
self.logger.info("Timeloop now started. Jobs will run based on the interval set")
if block:
self._block_main_thread()

View file

@ -17,10 +17,3 @@ class Job(Thread):
def run(self):
while not self.stopped.wait(self.interval.total_seconds()):
self.execute(*self.args, **self.kwargs)
def sample_func(arg1, arg2, arg3):
print "returning {} {} {}".format(arg1, arg2, arg3)
if __name__ == "__main__":
j = Job(timedelta(seconds=5), sample_func, **{"arg1": "sankalp", "arg2": "jonna", "arg3": "newsomething"})
j.start()