dbader / schedule

Python job scheduling for humans.
https://schedule.readthedocs.io/
MIT License
11.83k stars 965 forks source link

Failure of scheduled jobs that are staged to run at the same time? #475

Closed dachshund-digital closed 3 years ago

dachshund-digital commented 3 years ago

I schedule two jobs, to run every second...

schedule.every(1).seconds.do(DoOne) schedule.every(1).seconds.do(DoTwo)

The DoOne task or function is called every second as expected. But the DoTwo task is never called? Is this by design, or is this a bug?

dachshund-digital commented 3 years ago

Is anyone actively supporting this module? Seem like a lot of issue that are not being addressed?

rocky4546 commented 3 years ago

I do not seem to have the same issue, but I don't try to do something every second. I would be curious if this occurs when you setup the events ... say ... 10 seconds apart, so the app might have time to setup the next event. Also, I assume the two methods are very simple, like print('DoOne').

dachshund-digital commented 3 years ago

The tasks actually being done are less than a second duration. But the 2nd task never seems to fire. The documentation states that schedule does not support multiple tasks for the same schedule point. Hence my question. I will test a bit more, changing the scheduling as you noted. But I do need to run two tasks every second, so schedule may not be an option it seems? I am also changing the run_pending logic so it runs in a completely different process, but there may still be a blocking issue of some type for the 2nd task.

dachshund-digital commented 3 years ago

Ok, the good news is, there is not a design limitation of schedule as once suspected based on the documentation, you can get schedule to execute more than one job at the same exact time, i.e. multiple jobs at a 1 second interval. I wrote a simple python script that schedules two 1 second interval jobs, and spawns a multiprocesssing process object to let schedule.run_pending run as fast as possible, given the circumstances. This works, for example:

# python3 Explore.py Start Still Here Id 22064, State True Up... ...Down Up... ...Down Up... ...Down Up... ...Down Alive? Exit Join Bye

Of course the all the scheduled tasks run by schedule, at that 1 second interval, have to fast, or otherwise hand off to a queue, etc., because if the total tasks execution takes too long, i.e. more than 1 second in total for all tasks, you have other issues to deal with.

Here is some sample code that illustrates tasking that does complete 2 tasks in less than 1 second, at least on the system used.

\#!/usr/bin/python3

import multiprocessing, time, sys, os, schedule

theManager=multiprocessing.Manager()
theData=theManager.dict ({ 'id': None, 'state': True })

def Up():
        print('Up...')

def Down():
        print('...Down')

def Process(theData):
        theData['id']=os.getpid()
        print('Id {0}, State {1}'.format(theData['id'], theData['state']))
        while (theData['state']):
                schedule.run_pending()
                time.sleep(0.1)
        print('Bye')

theProcess=multiprocessing.Process(target=Process, args=(theData,))

try:
        schedule.every(1).seconds.do(Up)
        schedule.every(1).seconds.do(Down)
        theProcess.start()
        print('Start')
        print('Still Here')
        time.sleep(5)
except KeyboardInterrupt as theException:
        pass
except Exception as theException:
        print(theException)
finally:
        schedule.cancel_job(Down)
        schedule.cancel_job(Up)

        print('Alive?')
        if (theProcess.is_alive()):
                print('Exit')
                theData['state']=False
                print('Join')
                theProcess.join(5)

                if (theProcess.is_alive()):
                        print('Still Alive')
sys.exit(0)
dachshund-digital commented 3 years ago

WHY does the insert code feature FAIL SO BAD on this site? I digress, yes... but it is really frustrating.