Files
onepilot/frogpilot/third_party/reactivex/operators/_timeout.py
T
firestar5683 d0e1db6766 StarPilot
2026-03-22 03:15:05 -05:00

102 lines
3.2 KiB
Python

from asyncio import Future
from datetime import datetime
from typing import Any, Callable, Optional, TypeVar, Union
from reactivex import Observable, abc, from_future, throw, typing
from reactivex.disposable import (
CompositeDisposable,
SerialDisposable,
SingleAssignmentDisposable,
)
from reactivex.scheduler import TimeoutScheduler
_T = TypeVar("_T")
def timeout_(
duetime: typing.AbsoluteOrRelativeTime,
other: Optional[Union[Observable[_T], "Future[_T]"]] = None,
scheduler: Optional[abc.SchedulerBase] = None,
) -> Callable[[Observable[_T]], Observable[_T]]:
other = other or throw(Exception("Timeout"))
if isinstance(other, Future):
obs = from_future(other)
else:
obs = other
def timeout(source: Observable[_T]) -> Observable[_T]:
"""Returns the source observable sequence or the other observable
sequence if duetime elapses.
Examples:
>>> res = timeout(source)
Args:
source: Source observable to timeout
Returns:
An obserable sequence switching to the other sequence in
case of a timeout.
"""
def subscribe(
observer: abc.ObserverBase[_T],
scheduler_: Optional[abc.SchedulerBase] = None,
) -> abc.DisposableBase:
_scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
switched = [False]
_id = [0]
original = SingleAssignmentDisposable()
subscription = SerialDisposable()
timer = SerialDisposable()
subscription.disposable = original
def create_timer() -> None:
my_id = _id[0]
def action(scheduler: abc.SchedulerBase, state: Any = None):
switched[0] = _id[0] == my_id
timer_wins = switched[0]
if timer_wins:
subscription.disposable = obs.subscribe(
observer, scheduler=scheduler
)
if isinstance(duetime, datetime):
timer.disposable = _scheduler.schedule_absolute(duetime, action)
else:
timer.disposable = _scheduler.schedule_relative(duetime, action)
create_timer()
def on_next(value: _T) -> None:
send_wins = not switched[0]
if send_wins:
_id[0] += 1
observer.on_next(value)
create_timer()
def on_error(error: Exception) -> None:
on_error_wins = not switched[0]
if on_error_wins:
_id[0] += 1
observer.on_error(error)
def on_completed() -> None:
on_completed_wins = not switched[0]
if on_completed_wins:
_id[0] += 1
observer.on_completed()
original.disposable = source.subscribe(
on_next, on_error, on_completed, scheduler=scheduler_
)
return CompositeDisposable(subscription, timer)
return Observable(subscribe)
return timeout