_memory.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # -*- test-case-name: twisted._threads.test.test_memory -*-
  2. # Copyright (c) Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. """
  5. Implementation of an in-memory worker that defers execution.
  6. """
  7. from __future__ import annotations
  8. from enum import Enum, auto
  9. from typing import Callable, Literal
  10. from zope.interface import implementer
  11. from ._convenience import Quit
  12. from ._ithreads import IExclusiveWorker
  13. class NoMore(Enum):
  14. Work = auto()
  15. NoMoreWork = NoMore.Work
  16. @implementer(IExclusiveWorker)
  17. class MemoryWorker:
  18. """
  19. An L{IWorker} that queues work for later performance.
  20. @ivar _quit: a flag indicating
  21. @type _quit: L{Quit}
  22. """
  23. def __init__(
  24. self,
  25. pending: Callable[[], list[Callable[[], object] | Literal[NoMore.Work]]] = list,
  26. ) -> None:
  27. """
  28. Create a L{MemoryWorker}.
  29. """
  30. self._quit = Quit()
  31. self._pending = pending()
  32. def do(self, work: Callable[[], object]) -> None:
  33. """
  34. Queue some work for to perform later; see L{createMemoryWorker}.
  35. @param work: The work to perform.
  36. """
  37. self._quit.check()
  38. self._pending.append(work)
  39. def quit(self) -> None:
  40. """
  41. Quit this worker.
  42. """
  43. self._quit.set()
  44. self._pending.append(NoMoreWork)
  45. def createMemoryWorker() -> tuple[MemoryWorker, Callable[[], bool]]:
  46. """
  47. Create an L{IWorker} that does nothing but defer work, to be performed
  48. later.
  49. @return: a worker that will enqueue work to perform later, and a callable
  50. that will perform one element of that work.
  51. """
  52. def perform() -> bool:
  53. if not worker._pending:
  54. return False
  55. peek = worker._pending[0]
  56. if peek is NoMoreWork:
  57. return False
  58. worker._pending.pop(0)
  59. peek()
  60. return True
  61. worker = MemoryWorker()
  62. return (worker, perform)