asyncio.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from __future__ import absolute_import
  2. import asyncio
  3. from functools import wraps, partial
  4. from apscheduler.schedulers.base import BaseScheduler
  5. from apscheduler.util import maybe_ref
  6. def run_in_event_loop(func):
  7. @wraps(func)
  8. def wrapper(self, *args, **kwargs):
  9. wrapped = partial(func, self, *args, **kwargs)
  10. self._eventloop.call_soon_threadsafe(wrapped)
  11. return wrapper
  12. class AsyncIOScheduler(BaseScheduler):
  13. """
  14. A scheduler that runs on an asyncio (:pep:`3156`) event loop.
  15. The default executor can run jobs based on native coroutines (``async def``).
  16. Extra options:
  17. ============== =============================================================
  18. ``event_loop`` AsyncIO event loop to use (defaults to the global event loop)
  19. ============== =============================================================
  20. """
  21. _eventloop = None
  22. _timeout = None
  23. def start(self, paused=False):
  24. if not self._eventloop:
  25. self._eventloop = asyncio.get_event_loop()
  26. super(AsyncIOScheduler, self).start(paused)
  27. @run_in_event_loop
  28. def shutdown(self, wait=True):
  29. super(AsyncIOScheduler, self).shutdown(wait)
  30. self._stop_timer()
  31. def _configure(self, config):
  32. self._eventloop = maybe_ref(config.pop('event_loop', None))
  33. super(AsyncIOScheduler, self)._configure(config)
  34. def _start_timer(self, wait_seconds):
  35. self._stop_timer()
  36. if wait_seconds is not None:
  37. self._timeout = self._eventloop.call_later(wait_seconds, self.wakeup)
  38. def _stop_timer(self):
  39. if self._timeout:
  40. self._timeout.cancel()
  41. del self._timeout
  42. @run_in_event_loop
  43. def wakeup(self):
  44. self._stop_timer()
  45. wait_seconds = self._process_jobs()
  46. self._start_timer(wait_seconds)
  47. def _create_default_executor(self):
  48. from apscheduler.executors.asyncio import AsyncIOExecutor
  49. return AsyncIOExecutor()