1########################## 2Frequently Asked Questions 3########################## 4 5Why doesn't the scheduler run my jobs? 6====================================== 7 8This could be caused by a number of things. The two most common issues are: 9 10#. Running the scheduler inside a uWSGI worker process while threads have not been enabled (see the 11 next section for this) 12#. Running a :class:`~apscheduler.schedulers.background.BackgroundScheduler` and then letting the 13 execution reach the end of the script 14 15To demonstrate the latter case, a script like this will **not work**:: 16 17 from apscheduler.schedulers.background import BackgroundScheduler 18 19 def myjob(): 20 print('hello') 21 22 scheduler = BackgroundScheduler() 23 scheduler.start() 24 scheduler.add_job(myjob, 'cron', hour=0) 25 26The script above will **exit** right after calling ``add_job()`` so the scheduler will not have a 27chance to run the scheduled job. 28 29If you're having any other issue, then enabling debug logging as instructed in the 30:ref:`troubleshooting` section should shed some light into the problem. 31 32Why am I getting a ValueError? 33============================== 34 35If you're receiving an error like the following:: 36 37 ValueError: This Job cannot be serialized since the reference to its callable (<bound method xxxxxxxx.on_crn_field_submission 38 of <__main__.xxxxxxx object at xxxxxxxxxxxxx>>) could not be determined. Consider giving a textual reference (module:function 39 name) instead. 40 41This means that the function you are attempting to schedule has one of the following problems: 42 43* It is a lambda function (e.g. ``lambda x: x + 1``) 44* It is a bound method (function tied to a particular instance of some class) 45* It is a nested function (function inside another function) 46* You are trying to schedule a function that is not tied to any actual module (such as a function 47 defined in the REPL, hence ``__main__`` as the module name) 48 49In these cases, it is impossible for the scheduler to determine a "lookup path" to find that 50specific function instance in situations where, for example, the scheduler process is restarted, 51or a process pool worker is being sent the related job object. 52 53Common workarounds for these problems include: 54 55* Converting a lambda to a regular function 56* Moving a nested function to the module level or to class level as either a class method or a 57 static method 58* In case of a bound method, passing the unbound version (``YourClass.method_name``) as the target 59 function to ``add_job()`` with the class instance as the first argument (so it gets passed as the 60 ``self`` argument) 61 62How can I use APScheduler with uWSGI? 63===================================== 64 65uWSGI employs some tricks which disable the Global Interpreter Lock and with it, the use of threads 66which are vital to the operation of APScheduler. To fix this, you need to re-enable the GIL using 67the ``--enable-threads`` switch. See the `uWSGI documentation <uWSGI-threads>`_ for more details. 68 69Also, assuming that you will run more than one worker process (as you typically would in 70production), you should also read the next section. 71 72.. _uWSGI-threads: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#a-note-on-python-threads 73 74How do I share a single job store among one or more worker processes? 75===================================================================== 76 77Short answer: You can't. 78 79Long answer: Sharing a persistent job store among two or more processes will lead to incorrect 80scheduler behavior like duplicate execution or the scheduler missing jobs, etc. This is because 81APScheduler does not currently have any interprocess synchronization and signalling scheme that 82would enable the scheduler to be notified when a job has been added, modified or removed from a job 83store. 84 85Workaround: Run the scheduler in a dedicated process and connect to it via some sort of remote 86access mechanism like RPyC_, gRPC_ or an HTTP server. The source repository contains an example_ of 87a RPyC based service that is accessed by a client. 88 89.. _RPyC: https://rpyc.readthedocs.io/en/latest/ 90.. _gRPC: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwj-wMe-1eLcAhXSbZoKHdzGDZsQFjAAegQICRAB&url=https%3A%2F%2Fgrpc.io%2F&usg=AOvVaw0Jt5Y0OKbHd8MdFt9Kc2FO 91.. _example: https://github.com/agronholm/apscheduler/tree/3.x/examples/rpc 92 93How do I use APScheduler in a web application? 94============================================== 95 96First read through the previous section. 97 98If you're running Django, you may want to check out django_apscheduler_. Note, however, that this 99is a third party library and APScheduler developers are not responsible for it. 100 101Likewise, there is an unofficial extension called Flask-APScheduler_ which may or may not be useful 102when running APScheduler with Flask. 103 104For Pyramid users, the pyramid_scheduler_ library may potentially be helpful. 105 106Other than that, you pretty much run APScheduler normally, usually using 107:class:`~apscheduler.schedulers.background.BackgroundScheduler`. If you're running an asynchronous 108web framework like aiohttp_, you probably want to use a different scheduler in order to take some 109advantage of the asynchronous nature of the framework. 110 111Is there a graphical user interface for APScheduler? 112==================================================== 113 114No graphical interface is provided by the library itself. However, there are some third party 115implementations, but APScheduler developers are not responsible for them. Here is a potentially 116incomplete list: 117 118* django_apscheduler_ 119* apschedulerweb_ 120* `Nextdoor scheduler`_ 121 122.. _django_apscheduler: https://pypi.org/project/django-apscheduler/ 123.. _Flask-APScheduler: https://pypi.org/project/flask-apscheduler/ 124.. _pyramid_scheduler: https://github.com/cadithealth/pyramid_scheduler 125.. _aiohttp: https://pypi.org/project/aiohttp/ 126.. _apschedulerweb: https://github.com/marwinxxii/apschedulerweb 127.. _Nextdoor scheduler: https://github.com/Nextdoor/ndscheduler 128