示例#1
0
    class AsyncLockScheduler(Scheduler):
        def __init__(self):
            super(ImmediateScheduler.AsyncLockScheduler, self).__init__()
            self.gate = None

        def _scheduleCore(self, state, action):
            m = SingleAssignmentDisposable()

            def gated():
                if not m.isDisposed:
                    m.disposable = action(self, state)

            if self.gate == None:
                self.gate = AsyncLock()

            self.gate.wait(gated)

            return m

        def _scheduleRelativeCore(self, state, dueTime, action):
            m = SingleAssignmentDisposable()
            now = Scheduler.now()

            def gated():
                if not m.isDisposed:
                    elapsed = Scheduler.now() - now
                    dt = Scheduler.normalize(dueTime - elapsed)

                    if dt > 0:
                        sleep(dt)

                    if not m.isDisposed:
                        m.disposable = action(self, state)

            if self.gate == None:
                self.gate = AsyncLock()

            self.gate.wait(gated)

            return m

        def _scheduleAbsoluteCore(self, state, dueTime, action):
            return self.scheduleWithRelativeAndState(state,
                                                     dueTime - self.now(),
                                                     action)
示例#2
0
    def schedulePeriodicWithState(self, state, interval, action):
        gate = AsyncLock()

        def gated():
            state = action(state)

        timer = PeriodicTimer(interval, lambda: gate.wait(gated))
        cancel = timer.start()

        return CompositeDisposable(cancel, gate)
示例#3
0
  class AsyncLockScheduler(Scheduler):
    def __init__(self):
      super(ImmediateScheduler.AsyncLockScheduler, self).__init__()
      self.gate = None

    def _scheduleCore(self, state, action):
      m = SingleAssignmentDisposable()

      def gated():
        if not m.isDisposed:
          m.disposable = action(self, state)

      if self.gate == None:
        self.gate = AsyncLock()

      self.gate.wait(gated)

      return m

    def _scheduleRelativeCore(self, state, dueTime, action):
      m = SingleAssignmentDisposable()
      now = Scheduler.now()

      def gated():
        if not m.isDisposed:
          elapsed = Scheduler.now() - now
          dt = Scheduler.normalize(dueTime - elapsed)

          if dt > 0:
            sleep(dt)

          if not m.isDisposed:
            m.disposable = action(self, state)

      if self.gate == None:
        self.gate = AsyncLock()

      self.gate.wait(gated)

      return m

    def _scheduleAbsoluteCore(self, state, dueTime, action):
      return self.scheduleWithRelativeAndState(state, dueTime - self.now(), action)
示例#4
0
  def schedulePeriodicWithState(self, state, interval, action):
    gate = AsyncLock()

    def gated():
      state = action(state)

    timer = PeriodicTimer(interval, lambda: gate.wait(gated))
    cancel = timer.start()

    return CompositeDisposable(cancel, gate)
示例#5
0
文件: sink.py 项目: aguil/RxPython
class TailRecursiveSink(Sink):
  def __init__(self, observer, cancel):
    super(TailRecursiveSink, self).__init__(observer, cancel)

  @staticmethod
  def unpack(source):
    while hasattr(source, 'eval'):
      source = source.eval()

    return source

  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))
    )

  def extract(self, source):
    raise NotImplementedError()

  def moveNext(self):
    hasCurrent = False
    current = None

    while True:
      if len(self.stack) == 0:
        break

      if self.isDisposed:
        return

      e = self.stack[-1]
      l = self.length[-1]

      try:
        current = next(e)
        hasCurrent = True
      except StopIteration:
        pass
      except Exception as e:
        self.observer.onError(e)
        self.dispose()
        return

      if not hasCurrent:
        self.stack.pop()
        self.length.pop()
      else:
        r = l - 1
        self.length[-1] = r

        try:
          current = TailRecursiveSink.unpack(current)
        except Exception as e:
          self.observer.onError(e)
          self.dispose()
          return

        # Tail recursive case; drop the current frame.
        if r == 0:
          self.stack.pop()
          self.length.pop()

        # Flattening of nested sequences. Prevents stack overflow in observers.
        nextSeq = self.extract(current)

        if nextSeq != None:
          self.stack.append(iter(nextSeq))

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

          hasCurrent = False

      if hasCurrent:
        break

    if not hasCurrent:
      self.done()
      return

    d = SingleAssignmentDisposable()
    self.subscription.disposable = d
    d.disposable = current.subscribeSafe(self)

  def dispose(self):
    self.stack.clear()
    self.length.clear()
    self.isDisposed = True

  def done(self):
    self.observer.onCompleted()
    self.dispose()
示例#6
0
文件: sink.py 项目: aguil/RxPython
class TailRecursiveSink(Sink):
    def __init__(self, observer, cancel):
        super(TailRecursiveSink, self).__init__(observer, cancel)

    @staticmethod
    def unpack(source):
        while hasattr(source, 'eval'):
            source = source.eval()

        return source

    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)))

    def extract(self, source):
        raise NotImplementedError()

    def moveNext(self):
        hasCurrent = False
        current = None

        while True:
            if len(self.stack) == 0:
                break

            if self.isDisposed:
                return

            e = self.stack[-1]
            l = self.length[-1]

            try:
                current = next(e)
                hasCurrent = True
            except StopIteration:
                pass
            except Exception as e:
                self.observer.onError(e)
                self.dispose()
                return

            if not hasCurrent:
                self.stack.pop()
                self.length.pop()
            else:
                r = l - 1
                self.length[-1] = r

                try:
                    current = TailRecursiveSink.unpack(current)
                except Exception as e:
                    self.observer.onError(e)
                    self.dispose()
                    return

                # Tail recursive case; drop the current frame.
                if r == 0:
                    self.stack.pop()
                    self.length.pop()

                # Flattening of nested sequences. Prevents stack overflow in observers.
                nextSeq = self.extract(current)

                if nextSeq != None:
                    self.stack.append(iter(nextSeq))

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

                    hasCurrent = False

            if hasCurrent:
                break

        if not hasCurrent:
            self.done()
            return

        d = SingleAssignmentDisposable()
        self.subscription.disposable = d
        d.disposable = current.subscribeSafe(self)

    def dispose(self):
        self.stack.clear()
        self.length.clear()
        self.isDisposed = True

    def done(self):
        self.observer.onCompleted()
        self.dispose()