Example #1
0
    def invokeRec(self, scheduler, state):
      time = 0

      if self.hasResult:
        self.observer.onNext(self.result)

      try:
        if self.first:
          self.first = False
        else:
          state = self.parent.iterate(state)

        self.hasResult = self.parent.condition(state)

        if self.hasResult:
          self.result = self.parent.resultSelector(state)
          time = self.parent.timeSelector(state)
      except Exception as e:
        self.observer.onError(e)
        self.dispose()
        return Disposable.empty()

      if not self.hasResult:
        self.observer.onCompleted()
        self.dispose()
        return Disposable.empty()

      return self.parent.scheduler.scheduleWithRelativeAndState(
        state,
        time,
        self.invokeRec
      )
Example #2
0
        def invokeRec(self, scheduler, state):
            time = 0

            if self.hasResult:
                self.observer.onNext(self.result)

            try:
                if self.first:
                    self.first = False
                else:
                    state = self.parent.iterate(state)

                self.hasResult = self.parent.condition(state)

                if self.hasResult:
                    self.result = self.parent.resultSelector(state)
                    time = self.parent.timeSelector(state)
            except Exception as e:
                self.observer.onError(e)
                self.dispose()
                return Disposable.empty()

            if not self.hasResult:
                self.observer.onCompleted()
                self.dispose()
                return Disposable.empty()

            return self.parent.scheduler.scheduleWithRelativeAndState(
                state, time, self.invokeRec)
Example #3
0
    def connect(self, observer):
      #
      # We connect the given observer to the subject first, before performing any kind
      # of initialization which will register an event handler. This is done to ensure
      # we don't have a time gap between adding the handler and connecting the user's
      # subject, e.g. when the ImmediateScheduler is used.
      #
      # [OK] Use of unsafe Subscribe: called on a known subject implementation.
      #
      connection = self.subject.subscribe(observer)

      self.count += 1
      if self.count == 1:
        try:
          self.initialize()
        except Exception as e:
          self.count -= 1
          connection.dispose()

          observer.onError(e)
          return Disposable.empty()

      def dispose():
        connection.dispose()

        with self.parent.gate:
          self.count -=1
          if self.count == 0:
            self.parent.scheduler.schedule(self.removeHandler.dispose)
            self.parent.session = None

      return Disposable.create(dispose)
Example #4
0
def test_groupdisposable_clear():
    disp1 = [False]
    disp2 = [False]

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)

    g = CompositeDisposable(d1, d2)
    assert g.length == 2

    g.clear()
    assert disp1[0]
    assert disp2[0]
    assert not g.length

    disp3 = [False]

    def action3():
        disp3[0] = True

    d3 = Disposable(action3)
    g.add(d3)
    assert not disp3[0]
    assert g.length == 1
Example #5
0
  def subscribeCore(self, observer):
    old = None
    new = None

    while True:
      old = self.observer.value

      if old is DisposedObserver.instance:
        raise Exception("Object has been disposed")

      if old is DoneObserver.completed:
        observer.onCompleted()
        return Disposable.empty()

      if isinstance(old, DoneObserver):
        observer.onError(old.exception)
        return Disposable.empty()

      if old is NoopObserver.instance:
        new = observer
      else:
        if isinstance(old, ListObserver):
          new = old.add(observer)
        else:
          new = ListObserver((old, observer))

      current = self.observer.compareExchange(new, old)

      if old is current:
        break

    return self.Subscription(self, observer)
Example #6
0
    def subscribeCore(self, observer):
        old = None
        new = None

        while True:
            old = self.observer.value

            if old is DisposedObserver.instance:
                raise Exception("Object has been disposed")

            if old is DoneObserver.completed:
                observer.onCompleted()
                return Disposable.empty()

            if isinstance(old, DoneObserver):
                observer.onError(old.exception)
                return Disposable.empty()

            if old is NoopObserver.instance:
                new = observer
            else:
                if isinstance(old, ListObserver):
                    new = old.add(observer)
                else:
                    new = ListObserver((old, observer))

            current = self.observer.compareExchange(new, old)

            if old is current:
                break

        return self.Subscription(self, observer)
Example #7
0
def test_groupdisposable_contains():
    d1 = Disposable()
    d2 = Disposable()

    g = CompositeDisposable(d1, d2)

    assert g.length == 2
    assert g.contains(d1)
    assert g.contains(d2)
Example #8
0
    def wrapper(observer):
        a = subscribe(observer)

        if isinstance(a, Disposable):
            return a
        elif callable(a):
            return Disposable.create(a)
        else:
            return Disposable.empty()
Example #9
0
  def wrapper(observer):
    a = subscribe(observer)

    if isinstance(a, Disposable):
      return a
    elif callable(a):
      return Disposable.create(a)
    else:
      return Disposable.empty()
Example #10
0
def test_Disposable_dispose():
    disposed = [False]

    def action():
        disposed[0] = True

    d = Disposable(action)
    assert not disposed[0]
    d.dispose()
    assert disposed[0]
def test_Disposable_dispose():
    disposed = [False]

    def action():
        disposed[0] = True

    d = Disposable(action)
    assert not disposed[0]
    d.dispose()
    assert disposed[0]
Example #12
0
    def _subscribe_core(self, observer: Observer, scheduler: Scheduler = None) -> typing.Disposable:
        with self.lock:
            self.check_disposed()
            if not self.is_stopped:
                self.observers.append(observer)
                return InnerSubscription(self, observer)

            if self.exception:
                observer.on_error(self.exception)
                return Disposable()

            observer.on_completed()
            return Disposable()
Example #13
0
    def run(self):
      srcs = list(self.parent.sources)

      N = len(srcs)

      self.queues = [None] * N
      self.isDone = [False] * N
      self.subscriptions = [None] * N
      self.gate = RLock()

      for i in range(0, N):
        self.queues[i] = deque()

      # Loop twice because subscribing could already yield
      # a value before all queues are initialized
      for i in range(0, N):
        d = SingleAssignmentDisposable()
        self.subscriptions[i] = d

        o = self.O(self, i)
        d.disposable = srcs[i].subscribeSafe(o)

      c = CompositeDisposable(self.subscriptions)

      def dispose():
        for q in self.queues:
          q.clear()

      c.add(Disposable.create(dispose))

      return c
Example #14
0
    def _wxtimer_schedule(self,
                          time: typing.AbsoluteOrRelativeTime,
                          action: typing.ScheduledSingleOrPeriodicAction,
                          state: Optional[typing.TState] = None,
                          periodic: bool = False) -> typing.Disposable:
        scheduler = self

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            nonlocal state
            if periodic:
                state = action(state)
            else:
                sad.disposable = action(scheduler, state)

        msecs = int(self.to_seconds(time) * 1000.0)

        log.debug("timeout wx: %s", msecs)

        timer = self._timer_class(interval)
        timer.Start(
            msecs,
            self.wx.TIMER_CONTINUOUS if periodic else self.wx.TIMER_ONE_SHOT)
        self._timers.add(timer)

        def dispose() -> None:
            timer.Stop()
            self._timers.remove(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Example #15
0
    def schedule_absolute(
            self,
            duetime: typing.AbsoluteTime,
            action: typing.ScheduledAction,
            state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed at duetime.

        Args:
            duetime: Absolute time at which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        if self._is_disposed:
            raise DisposedException()

        dt = self.to_datetime(duetime)
        si: ScheduledItem[typing.TState] = ScheduledItem(
            self, state, action, dt)

        with self._condition:
            if dt <= self.now:
                self._ready_list.append(si)
            else:
                self._queue.enqueue(si)
            self._condition.notify()  # signal that a new item is available
            self._ensure_thread()

        return Disposable(si.cancel)
    def schedule_relative(
            self,
            duetime: RelativeTime,
            action,
            state=None,
    ):
        if isinstance(duetime, datetime.datetime):
            timedelta = duetime - datetime.datetime.fromtimestamp(0)
            timespan = float(timedelta.total_seconds())
        elif isinstance(duetime, datetime.timedelta):
            timespan = float(duetime.total_seconds())
        else:
            timespan = duetime

        def func():
            action(self, None)

        disposable = [MultipleAssignmentDisposable()]

        def _():
            def __():
                future = self.executor.submit(func)
                disposable[0] = Disposable(lambda: future.cancel())
            self.loop.call_later(timespan, __)

        future = self.loop.call_soon_threadsafe(_)
        return CompositeDisposable(disposable, Disposable(lambda: future.cancel()))
Example #17
0
    def _subscribe_core(self, observer=None, scheduler=None) -> typing.Disposable:
        clock = self.scheduler.to_seconds(self.scheduler.now)
        self.subscriptions.append(Subscription(clock))
        index = len(self.subscriptions) - 1
        disp = CompositeDisposable()

        def get_action(notification):
            def action(scheduler, state):
                notification.accept(observer)
                return Disposable()
            return action

        for message in self.messages:
            notification = message.value

            # Don't make closures within a loop
            action = get_action(notification)
            disp.add(self.scheduler.schedule_relative(message.time, action))

        def dispose() -> None:
            start = self.subscriptions[index].subscribe
            end = self.scheduler.to_seconds(self.scheduler.now)
            self.subscriptions[index] = Subscription(start, end)
            disp.dispose()

        return Disposable(dispose)
Example #18
0
  def subscribeCore(self, observer):
    index = len(self.subscriptions)

    self.observers.append(observer)
    self.subscriptions.append(Struct(
      subscribe=self.scheduler.now(),
      unsubscribe=0
    ))

    def scheduled(_, message):
      # time = message[0]
      notification = message[1]

      notification.accept(observer)

      return Disposable.empty()

    for m in self.messages:
      self.scheduler.scheduleWithRelativeAndState(m, m[0], scheduled)


    def dispose():
      self.observers.remove(observer)
      self.subscriptions[index].unsubscribe = self.scheduler.now()

    return Disposable.create(dispose)
Example #19
0
    def schedule_periodic(self,
                          period: typing.RelativeTime,
                          action: typing.ScheduledPeriodicAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedule a periodic piece of work."""

        secs: float = self.to_seconds(period)
        disposed: threading.Event = threading.Event()

        s = state

        def run() -> None:
            while True:
                disposed.wait(secs)
                if disposed.is_set():
                    return

                nonlocal s
                new_state = action(s)
                if new_state is not None:
                    s = new_state

        thread = self.thread_factory(run)
        thread.start()

        def dispose() -> None:
            disposed.set()

        return Disposable(dispose)
Example #20
0
    def propagate(self, scheduler, currentId):
      with self.gate:
        if self.hasValue and self.resourceId == currentId:
          self.observer.onNext(self.value)
        self.hasValue = False

      return Disposable.empty()
Example #21
0
    def schedule_periodic(self, period: typing.RelativeTime, action: typing.ScheduledPeriodicAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedule a periodic piece of work."""

        secs = self.to_seconds(period)
        disposed: List[bool] = []

        s = [state]

        def run() -> None:
            while True:
                time.sleep(secs)
                if disposed:
                    return

                new_state = action(s[0])
                if new_state is not None:
                    s[0] = new_state

        thread = self.thread_factory(run)
        thread.start()

        def dispose():
            disposed.append(True)

        return Disposable(dispose)
Example #22
0
    def scheduled(_, message):
      # time = message[0]
      notification = message[1]

      notification.accept(observer)

      return Disposable.empty()
Example #23
0
        def run(self):
            srcs = list(self.parent.sources)

            N = len(srcs)

            self.queues = [None] * N
            self.isDone = [False] * N
            self.subscriptions = [None] * N
            self.gate = RLock()

            for i in range(0, N):
                self.queues[i] = deque()

            # Loop twice because subscribing could already yield
            # a value before all queues are initialized
            for i in range(0, N):
                d = SingleAssignmentDisposable()
                self.subscriptions[i] = d

                o = self.O(self, i)
                d.disposable = srcs[i].subscribeSafe(o)

            c = CompositeDisposable(self.subscriptions)

            def dispose():
                for q in self.queues:
                    q.clear()

            c.add(Disposable.create(dispose))

            return c
Example #24
0
    def subscribeCore(self, observer):
        ex = None
        v = None
        hv = False

        with self.gate:
            errorIfDisposed(self)

            if not self.isStopped:
                self.observers.append(observer)
                return Subject.Subscription(self, observer)

            ex = self.exception
            hv = self.hasValue
            v = self.value

        if ex != None:
            observer.onError(ex)
        elif hv:
            observer.onNext(v)
            observer.onCompleted()
        else:
            observer.onCompleted()

        return Disposable.empty()
    def observe(self, observer_info: ObserverInfo):
        self.observer = observer_info.observer

        def dispose_func():
            self.is_disposed = True

        return Disposable(dispose_func)
    def schedule(self,
                 action: typing.ScheduledAction,
                 state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()
        disposed = False

        def interval() -> None:
            if not disposed:
                sad.disposable = self.invoke_action(action, state=state)

        self._loop.add_callback(interval)

        def dispose() -> None:
            nonlocal disposed
            disposed = True

        return CompositeDisposable(sad, Disposable(dispose))
Example #27
0
    def schedule_relative(self, duetime, action, state=None):
        """Schedules an action to be executed after duetime.

        Keyword arguments:
        duetime -- {timedelta} Relative time after which to execute the action.
        action -- {Function} Action to be executed.

        Returns {Disposable} The disposable object used to cancel the scheduled
        action (best effort)."""

        scheduler = self
        seconds = scheduler.to_seconds(duetime)
        if not seconds:
            return scheduler.schedule(action, state)

        sad = SingleAssignmentDisposable()

        def interval():
            sad.disposable = self.invoke_action(action, state)

        log.debug("timeout: %s", seconds)
        handle = self.loop.call_later(seconds, interval)

        def dispose():
            self.loop.remove_timeout(handle)

        return CompositeDisposable(sad, Disposable(dispose))
    def schedule_relative(
            self,
            duetime: typing.RelativeTime,
            action: typing.ScheduledAction,
            state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        sad = SingleAssignmentDisposable()
        is_disposed = False

        def invoke_action() -> None:
            if not is_disposed:
                sad.disposable = action(self, state)

        log.debug("relative timeout: %sms", msecs)

        # Use static method, let Qt C++ handle QTimer lifetime
        self._qtcore.QTimer.singleShot(msecs, invoke_action)

        def dispose() -> None:
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(sad, Disposable(dispose))
Example #29
0
    def schedule_relative(
            self,
            duetime: typing.RelativeTime,
            action: typing.ScheduledAction,
            state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        seconds = self.to_seconds(duetime)
        if not seconds:
            return self.schedule(action, state=state)

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        log.debug("timeout: %s", seconds)
        timer = gevent.spawn_later(seconds, interval)

        def dispose() -> None:
            timer.kill()

        return CompositeDisposable(sad, Disposable(dispose))
Example #30
0
  def subscribeCore(self, observer):
    d = self._subscribe(observer)

    if d == None:
      return Disposable.empty()
    else:
      return d
        def subscribe(
                observer: typing.Observer,
                scheduler: Optional[typing.Scheduler] = None
        ) -> typing.Disposable:
            def handler(*args):
                results = list(args)
                if mapper:
                    try:
                        results = mapper(args)
                    except Exception as err:  # pylint: disable=broad-except
                        observer.on_error(err)
                        return

                    observer.on_next(results)
                else:
                    if isinstance(results, list) and len(results) <= 1:
                        observer.on_next(*results)
                    else:
                        observer.on_next(results)

                    # observer.on_completed()

            arguments.append(handler)
            func(*arguments)
            return Disposable()
Example #32
0
        def fix_subscriber(subscriber):
            """Fixes subscriber to make sure it returns a Disposable instead
            of None or a dispose function"""
            if not hasattr(subscriber, "dispose"):
                subscriber = Disposable(subscriber)

            return subscriber
Example #33
0
    def schedule_relative(self, duetime: typing.RelativeTime, action: typing.ScheduledAction,
                          state: typing.TState = None) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def invoke_action():
            sad.disposable = self.invoke_action(action, state)

        msecs = int(self.to_seconds(duetime)*1000.0)
        alarm = self.master.after(msecs, invoke_action)

        def dispose():
            self.master.after_cancel(alarm)

        return CompositeDisposable(sad, Disposable(dispose))
Example #34
0
  def subscribeCore(self, observer):
    ex = None
    v = None
    hv = False

    with self.gate:
      errorIfDisposed(self)

      if not self.isStopped:
        self.observers.append(observer)
        return Subject.Subscription(self, observer)

      ex = self.exception
      hv = self.hasValue
      v = self.value

    if ex != None:
      observer.onError(ex)
    elif hv:
      observer.onNext(v)
      observer.onCompleted()
    else:
      observer.onCompleted()

    return Disposable.empty()
Example #35
0
    def _gtk_schedule(self,
                      time: typing.AbsoluteOrRelativeTime,
                      action: typing.ScheduledSingleOrPeriodicAction,
                      state: Optional[typing.TState] = None,
                      periodic: bool = False) -> typing.Disposable:
        # Do not import GLib into global scope because Qt and GLib
        # don't like each other there
        from gi.repository import GLib

        msecs = int(self.to_seconds(time) * 1000.0)

        sad = SingleAssignmentDisposable()

        periodic_state = state
        stopped = False

        def timer_handler(_) -> bool:
            if stopped:
                return False

            if periodic:
                nonlocal periodic_state
                periodic_state = action(periodic_state)
            else:
                sad.disposable = self.invoke_action(action, state=state)

            return periodic

        GLib.timeout_add(msecs, timer_handler, None)

        def dispose() -> None:
            nonlocal stopped
            stopped = True

        return CompositeDisposable(sad, Disposable(dispose))
Example #36
0
    def schedule(self,
                 action: typing.ScheduledAction,
                 state: Optional[typing.TState] = None) -> typing.Disposable:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        timer = gevent.spawn(interval)

        def dispose() -> None:
            timer.kill()

        return CompositeDisposable(sad, Disposable(dispose))
Example #37
0
    def _wxtimer_schedule(self, time, action, state, periodic=False):
        scheduler = self

        sad = SingleAssignmentDisposable()

        periodic_state = [state]

        def interval():
            if periodic:
                periodic_state[0] = action(periodic_state[0])
            else:
                sad.disposable = action(scheduler, state)

        log.debug("timeout: %s", msecs)

        msecs = int(self.to_seconds(time) * 1000.0)
        if msecs == 0:
            msecs = 1  # wx.Timer doesn't support zero.

        timer = self._timer_class(interval)
        timer.Start(
            msecs,
            self.wx.TIMER_CONTINUOUS if periodic else self.wx.TIMER_ONE_SHOT)
        self._timers.add(timer)

        def dispose():
            timer.Stop()
            self._timers.remove(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Example #38
0
    def _gtk_schedule(self, time, action, state, periodic=False):
        # Do not import GLib into global scope because Qt and GLib
        # don't like each other there
        from gi.repository import GLib

        scheduler = self
        msecs = int(self.to_seconds(time)*1000)

        sad = SingleAssignmentDisposable()

        periodic_state = [state]
        stopped = [False]

        def timer_handler(_):
            if stopped[0]:
                return False

            if periodic:
                periodic_state[0] = action(periodic_state[0])
            else:
                sad.disposable = action(scheduler, state)

            return periodic

        GLib.timeout_add(msecs, timer_handler, None)

        def dispose():
            stopped[0] = True

        return CompositeDisposable(sad, Disposable(dispose))
    def schedule_relative(self,
                          duetime: typing.RelativeTime,
                          action: typing.ScheduledAction,
                          state: Optional[typing.TState] = None
                          ) -> typing.Disposable:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def invoke_action() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        timer = self._root.after(msecs, invoke_action)

        def dispose() -> None:
            self._root.after_cancel(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Example #40
0
  def run(self, sources):
    self.isDisposed = False
    self.subscription = SerialDisposable()
    self.gate = AsyncLock()
    self.stack = []
    self.length = []

    self.stack.append(iter(sources))

    try:
      length = len(sources)
    except TypeError:
      self.length.append(-1)
    else:
      self.length.append(length)

    def scheduled(continuation):
      self.recurse = continuation
      self.gate.wait(self.moveNext)

    cancel = Scheduler.tailRecursion.scheduleRecursive(scheduled)

    return CompositeDisposable(
      self.subscription,
      cancel,
      Disposable.create(lambda: self.gate.wait(self.dispose))
    )
Example #41
0
  def scheduled():
    try:
      subject.onNext(action())
      subject.onCompleted()
    except Exception as e:
      subject.onError(e)

    return Disposable.empty()
Example #42
0
  def scheduledSubscribe(self, scheduler, autoDetachObserver):
    try:
      autoDetachObserver.disposable = self.subscribeCore(autoDetachObserver)
    except Exception as e:
      if not autoDetachObserver.fail(e):
        raise e

    return Disposable.empty()
Example #43
0
  def start(self):
    timer = Timer(self.interval, self._execute)

    self.timerDisposable.disposable = Disposable.create(timer.cancel)

    timer.start()

    return self.timerDisposable
Example #44
0
    def scheduled(_, message):
      # time = message[0]
      notification = message[1]

      for o in list(self.observers):
        notification.accept(o)

      return Disposable.empty()
Example #45
0
    def scheduleDrain(self):
      def cancel():
        self.stopped = True
        self.stop.set()
        self.evt.release()

      self.stop.clear()
      self.cancelTimer.disposable = Disposable.create(cancel)
      self.scheduler.scheduleLongRunning(self.drainQueue)
Example #46
0
 def run(self):
   try:
     result = self.parent.eval()
   except Exception as e:
     self.observer.onError(e)
     self.dispose()
     return Disposable.empty()
   else:
     return result.subscribeSafe(self)
Example #47
0
    def run(self):
      def dispose():
        try:
          subscription.dispose()
        finally:
          self.parent.action()

      subscription = self.parent.source.subscribeSafe(self)
      return Disposable.create(dispose)
Example #48
0
  def schedulerCallback(self, scheduler, state):
    with self.lock:
      if self.isAdded:
        self.group.remove(self.cancel)
      else:
        self.isDone = True

    self.run(state)

    return Disposable.empty()
Example #49
0
  def _scheduleCore(self, state, action):
    d = SingleAssignmentDisposable()

    def scheduled():
      if not d.isDisposed:
        d.disposable = action(self, state)

    future = self.pool.submit(scheduled)
    cancel = Disposable.create(future.cancel)

    return CompositeDisposable(d, cancel)
Example #50
0
  def ensureDispatcher(self):
    if self.dispatcherJob != None:
      return

    with self.lock:
      if self.dispatcherJob == None:
        self.dispatcherJob = self.scheduler.scheduleLongRunning(self.dispatch)
        self.disposable.disposable = CompositeDisposable(
          self.dispatcherJob,
          Disposable.create(self.dispatcherEvent.release)
        )
Example #51
0
    def timeout(self, scheduler, currentId):
      timerWins = False

      with self.gate:
        self.switched = self.currentId == currentId
        timerWins = self.switched

      if timerWins:
        self.subscription.disposable = self.parent.other.subscribeSafe(self.getForewarder())

      return Disposable.empty()
Example #52
0
    def tick(self, scheduler, state):
      with self.gate:
        if state.isSpan:
          s = self.queue.popleft()
          s.onCompleted()

        if state.isShift:
          self.createWindow()

      self.createTimer()

      return Disposable.empty()
Example #53
0
  def subscribeCore(self, observer):
    index = len(self.subscriptions)

    self.observers.append(observer)
    self.subscriptions.append(Struct(
      subscribe=self.scheduler.now(),
      unsubscribe=0
    ))

    def dispose():
      self.observers.remove(observer)
      self.subscriptions[index].unsubscribe = self.scheduler.now()

    return Disposable.create(dispose)
Example #54
0
    def run(self):
      source = None
      disposable = Disposable.empty()

      try:
        resource = self.parent.resourceFactory()
        if resource != None:
          disposable = resource

        source = self.parent.observableFactory(resource)
      except Exception as e:
        return CompositeDisposable(Observable.throw(e).subscribeSafe(self), disposable)

      return CompositeDisposable(source.subscribeSafe(self), disposable)
Example #55
0
  def subscribeSafe(self, observer):
    if isinstance(self, ObservableBase):
      return self.subscribeCore(observer)
    elif isinstance(self, Producer):
      return self.subscribeRaw(observer, False)

    d = Disposable.empty()

    try:
      d = self.subscribeCore(observer)
    except Exception as e:
      observer.onError(e)

    return d
Example #56
0
  def _scheduleRelativeCore(self, state, dueTime, action):
    dt = Scheduler.normalize(dueTime)

    if dt == 0:
      return self.scheduleWithState(state, action)

    d = SingleAssignmentDisposable()

    def scheduled():
      if not d.isDisposed:
        d.disposable = action(self, state)

    timer = Timer(dt, scheduled)
    cancel = Disposable.create(timer.cancel)

    return CompositeDisposable(d, cancel)
Example #57
0
    def addHandler(self, scheduler, onNext):
      try:
        removeHandler = self.parent.addHandler(onNext)
      except Exception as e:
        self.subject.onError(e)
      else:
        self.removeHandler.disposable = removeHandler

      #
      # We don't propagate the exception to the OnError channel upon Dispose. This is
      # not possible at this stage, because we've already auto-detached in the base
      # class Producer implementation. Even if we would switch the OnError and auto-
      # detach calls, it wouldn't work because the remove handler logic is scheduled
      # on the given scheduler, causing asynchrony. We can't block waiting for the
      # remove handler to run on the scheduler.
      #
      return Disposable.empty()
Example #58
0
    def run(self):
      observable = None
      connectable = None

      try:
        subject = self.parent.subjectSelector()
        connectable = ConnectableObservable(self.parent.source, subject)
        observable = self.parent.selector(connectable)
      except Exception as e:
        self.observer.onError(e)
        self.dispose()
        return Disposable.empty()
      else:
        subscription = observable.subscribeSafe(self)
        connection = connectable.connect()

        return CompositeDisposable(subscription, connection)