offwork 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- offwork/__init__.py +167 -0
- offwork/__main__.py +770 -0
- offwork/_venv.py +174 -0
- offwork/core/__init__.py +15 -0
- offwork/core/errors.py +83 -0
- offwork/core/models.py +174 -0
- offwork/core/pairing.py +389 -0
- offwork/core/progress.py +91 -0
- offwork/core/signing.py +91 -0
- offwork/core/task.py +520 -0
- offwork/core/token.py +184 -0
- offwork/core/version.py +10 -0
- offwork/graph/__init__.py +5 -0
- offwork/graph/analyzer.py +637 -0
- offwork/graph/decorator.py +87 -0
- offwork/graph/graph.py +995 -0
- offwork/graph/store.py +500 -0
- offwork/graph/tracing.py +429 -0
- offwork/py.typed +0 -0
- offwork/typing.py +48 -0
- offwork/worker/__init__.py +18 -0
- offwork/worker/backends/__init__.py +3 -0
- offwork/worker/backends/base.py +149 -0
- offwork/worker/backends/http.py +237 -0
- offwork/worker/backends/local.py +452 -0
- offwork/worker/backends/rabbitmq.py +410 -0
- offwork/worker/backends/redis.py +175 -0
- offwork/worker/deps.py +365 -0
- offwork/worker/remote.py +793 -0
- offwork/worker/result.py +276 -0
- offwork/worker/sandbox/Dockerfile +24 -0
- offwork/worker/sandbox/__init__.py +18 -0
- offwork/worker/sandbox/_protocol.py +50 -0
- offwork/worker/sandbox/docker.py +438 -0
- offwork/worker/sandbox/guest_agent.py +622 -0
- offwork/worker/schedule.py +26 -0
- offwork/worker/worker.py +263 -0
- offwork-0.4.0.dist-info/METADATA +143 -0
- offwork-0.4.0.dist-info/RECORD +42 -0
- offwork-0.4.0.dist-info/WHEEL +4 -0
- offwork-0.4.0.dist-info/entry_points.txt +3 -0
- offwork-0.4.0.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""The ``@trace`` decorator for marking functions for remote execution."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from datetime import timedelta
|
|
5
|
+
from typing import TypeVar, ParamSpec, overload
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
|
|
8
|
+
from offwork.typing import TraceDecorator, TracedFunction
|
|
9
|
+
from offwork.graph.graph import Graph
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
_R = TypeVar("_R")
|
|
14
|
+
_P = ParamSpec("_P")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@overload
|
|
18
|
+
def trace(func: Callable[_P, _R]) -> TracedFunction[_P, _R]: ...
|
|
19
|
+
@overload
|
|
20
|
+
def trace(*, timeout: float | None = ..., retries: int = ..., retry_delay: float = ..., throttle: timedelta | float | None = ...) -> TraceDecorator: ...
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def trace(
|
|
24
|
+
func: Callable[..., object] | None = None,
|
|
25
|
+
*,
|
|
26
|
+
timeout: float | None = None,
|
|
27
|
+
retries: int = 0,
|
|
28
|
+
retry_delay: float = 1.0,
|
|
29
|
+
throttle: timedelta | float | None = None,
|
|
30
|
+
) -> object:
|
|
31
|
+
"""Enable a function for serialization and remote execution.
|
|
32
|
+
|
|
33
|
+
The decorated function works normally when called directly.
|
|
34
|
+
Call ``func.run(...)`` to submit it to a remote worker.
|
|
35
|
+
|
|
36
|
+
Can be used with or without arguments::
|
|
37
|
+
|
|
38
|
+
@trace
|
|
39
|
+
def fast(x): ...
|
|
40
|
+
|
|
41
|
+
@trace(timeout=30, retries=3)
|
|
42
|
+
def flaky(x): ...
|
|
43
|
+
"""
|
|
44
|
+
if func is not None:
|
|
45
|
+
return _apply_trace(func, timeout=timeout, retries=retries, retry_delay=retry_delay, throttle=throttle)
|
|
46
|
+
|
|
47
|
+
def decorator(f: Callable[_P, _R]) -> object:
|
|
48
|
+
return _apply_trace(f, timeout=timeout, retries=retries, retry_delay=retry_delay, throttle=throttle)
|
|
49
|
+
|
|
50
|
+
return decorator
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _apply_trace(
|
|
54
|
+
func: Callable[_P, _R],
|
|
55
|
+
*,
|
|
56
|
+
timeout: float | None = None,
|
|
57
|
+
retries: int = 0,
|
|
58
|
+
retry_delay: float = 1.0,
|
|
59
|
+
throttle: timedelta | float | None = None,
|
|
60
|
+
) -> TracedFunction[_P, _R]:
|
|
61
|
+
if timeout is not None and timeout <= 0:
|
|
62
|
+
raise ValueError(f"timeout must be positive, got {timeout}")
|
|
63
|
+
if retries < 0:
|
|
64
|
+
raise ValueError(f"retries must be non-negative, got {retries}")
|
|
65
|
+
if retry_delay < 0:
|
|
66
|
+
raise ValueError(f"retry_delay must be non-negative, got {retry_delay}")
|
|
67
|
+
|
|
68
|
+
throttle_seconds: float | None = None
|
|
69
|
+
if throttle is not None:
|
|
70
|
+
if isinstance(throttle, timedelta):
|
|
71
|
+
throttle_seconds = throttle.total_seconds()
|
|
72
|
+
else:
|
|
73
|
+
throttle_seconds = float(throttle)
|
|
74
|
+
if throttle_seconds <= 0:
|
|
75
|
+
raise ValueError(f"throttle must be positive, got {throttle}")
|
|
76
|
+
|
|
77
|
+
logger.debug("@trace applied to %s", func.__qualname__)
|
|
78
|
+
graph = Graph.default()
|
|
79
|
+
graph.register(func)
|
|
80
|
+
wrapper = graph.create_wrapper(func)
|
|
81
|
+
wrapper.__offwork_options__ = { # type: ignore[attr-defined]
|
|
82
|
+
"timeout": timeout,
|
|
83
|
+
"retries": retries,
|
|
84
|
+
"retry_delay": retry_delay,
|
|
85
|
+
"throttle": throttle_seconds,
|
|
86
|
+
}
|
|
87
|
+
return wrapper
|