Skip to content

Commit

Permalink
fix: add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
phi-friday committed Feb 29, 2024
1 parent 0ebe7e8 commit dae0f89
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/timeout_executor/const.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

__all__ = ["TIMEOUT_EXECUTOR_INPUT_FILE"]
__all__ = ["TIMEOUT_EXECUTOR_INPUT_FILE", "SUBPROCESS_COMMAND"]
TIMEOUT_EXECUTOR_INPUT_FILE = "_TIMEOUT_EXECUTOR_INPUT_FILE"
SUBPROCESS_COMMAND = (
"from timeout_executor.subprocess import run_in_subprocess;run_in_subprocess()"
Expand Down
46 changes: 46 additions & 0 deletions src/timeout_executor/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ def apply_func(
def apply_func(
timeout: float, func: Callable[P2, Any], *args: P2.args, **kwargs: P2.kwargs
) -> AsyncResult[Any]:
"""run function with deadline
Args:
timeout: deadline
func: func(sync or async)
Returns:
async result container
"""
executor = _Executor(timeout, func)
return executor.apply(*args, **kwargs)

Expand All @@ -127,11 +136,22 @@ async def delay_func(
async def delay_func(
timeout: float, func: Callable[P2, Any], *args: P2.args, **kwargs: P2.kwargs
) -> AsyncResult[Any]:
"""run function with deadline
Args:
timeout: deadline
func: func(sync or async)
Returns:
async result container
"""
executor = _Executor(timeout, func)
return await executor.delay(*args, **kwargs)


class TimeoutExecutor:
"""timeout executor"""

def __init__(self, timeout: float) -> None:
self._timeout = timeout

Expand All @@ -152,6 +172,14 @@ def apply(
def apply(
self, func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs
) -> AsyncResult[Any]:
"""run function with deadline
Args:
func: func(sync or async)
Returns:
async result container
"""
return apply_func(self._timeout, func, *args, **kwargs)

@overload
Expand All @@ -168,6 +196,14 @@ async def delay(
async def delay(
self, func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs
) -> AsyncResult[Any]:
"""run function with deadline
Args:
func: func(sync or async)
Returns:
async result container
"""
return await delay_func(self._timeout, func, *args, **kwargs)

@overload
Expand All @@ -184,6 +220,16 @@ async def apply_async(
async def apply_async(
self, func: Callable[P, Any], *args: P.args, **kwargs: P.kwargs
) -> AsyncResult[Any]:
"""run function with deadline.
alias of `delay`
Args:
func: func(sync or async)
Returns:
async result container
"""
return await self.delay(func, *args, **kwargs)


Expand Down
4 changes: 4 additions & 0 deletions src/timeout_executor/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@


class AsyncResult(Generic[T]):
"""async result container"""

_result: Any

def __init__(
Expand All @@ -44,10 +46,12 @@ def __init__(
self._input = input_file

def result(self, timeout: float | None = None) -> T:
"""get value sync method"""
future = async_to_sync(self.delay)
return future(timeout)

async def delay(self, timeout: float | None = None) -> T:
"""get value async method"""
try:
return await self._delay(timeout)
finally:
Expand Down
4 changes: 4 additions & 0 deletions src/timeout_executor/serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def serialize_traceback(traceback: TracebackType) -> tuple[Any, ...]:


def serialize_error(error: Exception) -> SerializedError:
"""serialize exception"""
exception = pickle_exception(error)[1:]

exception_args, exception = exception[0], exception[1:]
Expand Down Expand Up @@ -62,6 +63,7 @@ def serialize_error(error: Exception) -> SerializedError:


def deserialize_error(error: SerializedError) -> Exception:
"""deserialize exception"""
arg_exception: deque[Any] = deque(error.arg_exception)
arg_tracebacks: deque[tuple[int, tuple[Any, ...]]] = deque(error.arg_tracebacks)

Expand All @@ -79,13 +81,15 @@ def deserialize_error(error: SerializedError) -> Exception:


def dumps_error(error: Exception | SerializedError) -> bytes:
"""serialize exception as bytes"""
if not isinstance(error, SerializedError):
error = serialize_error(error)

return cloudpickle.dumps(error)


def loads_error(error: bytes | SerializedError) -> Exception:
"""deserialize exception from bytes"""
if isinstance(error, bytes):
error = cloudpickle.loads(error)
if not isinstance(error, SerializedError):
Expand Down

0 comments on commit dae0f89

Please sign in to comment.