Example #1
0
    class SinkWithTimeSpan(rx.linq.sink.Sink):
        def __init__(self, parent, observer, cancel):
            super(Window.SinkWithTimeSpan, self).__init__(observer, cancel)
            self.parent = parent

        def run(self):
            self.gate = RLock()

            groupDisposable = CompositeDisposable()
            self.refCountDisposable = RefCountDisposable(groupDisposable)

            self.createWindow()

            groupDisposable.add(
                self.parent.scheduler.schedulePeriodic(self.parent.timeSpan,
                                                       self.tick))
            groupDisposable.add(self.parent.source.subscribeSafe(self))

            return self.refCountDisposable

        def tick(self):
            with self.gate:
                self.subject.onCompleted()
                self.createWindow()

        def createWindow(self):
            self.subject = Subject()
            self.observer.onNext(AddRef(self.subject, self.refCountDisposable))

        def onNext(self, value):
            with self.gate:
                self.list.append(value)

        def onError(self, exception):
            with self.gate:
                self.subject.onError(exception)

                self.observer.onError(exception)
                self.dispose()

        def onCompleted(self):
            with self.gate:
                self.subject.onCompleted()

                self.observer.onCompleted()
                self.dispose()
Example #2
0
  class SinkWithTimeSpan(rx.linq.sink.Sink):
    def __init__(self, parent, observer, cancel):
      super(Window.SinkWithTimeSpan, self).__init__(observer, cancel)
      self.parent = parent

    def run(self):
      self.gate = RLock()

      groupDisposable = CompositeDisposable()
      self.refCountDisposable = RefCountDisposable(groupDisposable)

      self.createWindow()

      groupDisposable.add(self.parent.scheduler.schedulePeriodic(self.parent.timeSpan, self.tick))
      groupDisposable.add(self.parent.source.subscribeSafe(self))

      return self.refCountDisposable

    def tick(self):
      with self.gate:
        self.subject.onCompleted()
        self.createWindow()

    def createWindow(self):
      self.subject = Subject()
      self.observer.onNext(AddRef(self.subject, self.refCountDisposable))

    def onNext(self, value):
      with self.gate:
        self.list.append(value)

    def onError(self, exception):
      with self.gate:
        self.subject.onError(exception)

        self.observer.onError(exception)
        self.dispose()

    def onCompleted(self):
      with self.gate:
        self.subject.onCompleted()

        self.observer.onCompleted()
        self.dispose()
Example #3
0
  class Session(object):
    def __init__(self, parent):
      self.parent = parent
      self.removeHandler = None
      self.subject = Subject()
      self.count = 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)

    def initialize(self):
      #
      # When the ref count goes to zero, no-one should be able to perform operations on
      # the session object anymore, because it gets nulled out.
      #
      assert self.removeHandler == None
      self.removeHandler = SingleAssignmentDisposable()

      #
      # Conversion code is supposed to be a pure function and shouldn't be run on the
      # scheduler, but the add handler call should. Notice the scheduler can be the
      # ImmediateScheduler, causing synchronous invocation. This is the default when
      # no SynchronizationContext is found (see QueryLanguage.Events.cs and search for
      # the GetSchedulerForCurrentContext method).
      #

      onNext = self.parent.getHandler(self.subject.onNext)
      self.parent.scheduler.scheduleWithState(onNext, self.addHandler)

    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 #4
0
    class Sink(rx.linq.sink.Sink):
        def __init__(self, parent, observer, cancel):
            super(GroupBy.Sink, self).__init__(observer, cancel)
            self.parent = parent
            self.map = {}
            self.null = None

        def onNext(self, value):
            key = None

            try:
                key = self.parent.keySelector(value)
            except Exception as e:
                self.onError(e)
                return

            fireNewMapEntry = False
            writer = None

            try:
                if key == None:
                    if self.null == None:
                        self.null = Subject()
                        fireNewMapEntry = True

                    writer = self.null
                else:
                    if key in self.map:
                        writer = self.map[key]
                    else:
                        writer = Subject()
                        self.map[key] = writer
                        fireNewMapEntry = True
            except Exception as e:
                self.onError(e)
                return

            if fireNewMapEntry:
                group = GroupObservable(key, writer,
                                        self.parent.refCountDisposable)
                self.observer.onNext(group)

            element = None

            try:
                element = self.parent.elementSelector(value)
            except Exception as e:
                self.onError(e)
            else:
                writer.onNext(element)

        def onError(self, exception):
            if self.null != None:
                self.null.onError(exception)

            for x in self.map.values():
                x.onError(exception)

            self.observer.onError(exception)
            self.dispose()

        def onCompleted(self):
            if self.null != None:
                self.null.onCompleted()

            for x in self.map.values():
                x.onCompleted()

            self.observer.onCompleted()
            self.dispose()
Example #5
0
  class SinkWithCountAndTimeSpan(rx.linq.sink.Sink):
    def __init__(self, parent, observer, cancel):
      super(Window.SinkWithCountAndTimeSpan, self).__init__(observer, cancel)
      self.parent = parent

    def run(self):
      self.gate = RLock()
      self.s = Subject()
      self.n = 0
      self.windowId = 0

      self.timerDisposable = SerialDisposable()
      groupDisposable = CompositeDisposable(self.timerDisposable)
      self.refCountDisposable = RefCountDisposable(groupDisposable)

      # AddRef was originally WindowObservable but this is just an alias for AddRef
      self.observer.onNext(AddRef(self.s, self.refCountDisposable))
      self.createTimer(0)

      groupDisposable.add(self.parent.source.subscribeSafe(self))

      return self.refCountDisposable

    def createTimer(self, wId):
      m = SingleAssignmentDisposable()
      self.timerDisposable.disposable = m

      m.disposable = self.parent.scheduler.scheduleWithRelativeAndState(
        wId,
        self.parent.timeSpan,
        self.tick
      )

    def tick(self, scheduler, wId):
      d = Disposable.empty()

      newId = 0

      with self.gate:
        if wId != self.windowId:
          return d

        self.n = 0
        self.windowId += 1
        newId = self.windowId

        self.s.onCompleted()
        self.s = Subject()
        self.observer.onNext(AddRef(self.s, self.refCountDisposable))

      self.createTimer(newId)

      return d

    def onNext(self, value):
      newWindow = False
      newId = 0

      with self.gate:
        self.s.onNext(value)
        self.n += 1

        if self.n == self.parent.count:
          newWindow = True
          self.n = 0
          self.windowId += 1
          newId = self.windowId

          self.s.onCompleted()
          self.s = Subject()
          self.observer.onNext(AddRef(self.s, self.refCountDisposable))

      if newWindow:
        self.createTimer(newId)

    def onError(self, exception):
      with self.gate:
        self.s.onError(exception)
        self.observer.onError(exception)
        self.dispose()

    def onCompleted(self):
      with self.gate:
        self.s.onCompleted()
        self.observer.onCompleted()
        self.dispose()
Example #6
0
    class SinkWithCountAndTimeSpan(rx.linq.sink.Sink):
        def __init__(self, parent, observer, cancel):
            super(Window.SinkWithCountAndTimeSpan,
                  self).__init__(observer, cancel)
            self.parent = parent

        def run(self):
            self.gate = RLock()
            self.s = Subject()
            self.n = 0
            self.windowId = 0

            self.timerDisposable = SerialDisposable()
            groupDisposable = CompositeDisposable(self.timerDisposable)
            self.refCountDisposable = RefCountDisposable(groupDisposable)

            # AddRef was originally WindowObservable but this is just an alias for AddRef
            self.observer.onNext(AddRef(self.s, self.refCountDisposable))
            self.createTimer(0)

            groupDisposable.add(self.parent.source.subscribeSafe(self))

            return self.refCountDisposable

        def createTimer(self, wId):
            m = SingleAssignmentDisposable()
            self.timerDisposable.disposable = m

            m.disposable = self.parent.scheduler.scheduleWithRelativeAndState(
                wId, self.parent.timeSpan, self.tick)

        def tick(self, scheduler, wId):
            d = Disposable.empty()

            newId = 0

            with self.gate:
                if wId != self.windowId:
                    return d

                self.n = 0
                self.windowId += 1
                newId = self.windowId

                self.s.onCompleted()
                self.s = Subject()
                self.observer.onNext(AddRef(self.s, self.refCountDisposable))

            self.createTimer(newId)

            return d

        def onNext(self, value):
            newWindow = False
            newId = 0

            with self.gate:
                self.s.onNext(value)
                self.n += 1

                if self.n == self.parent.count:
                    newWindow = True
                    self.n = 0
                    self.windowId += 1
                    newId = self.windowId

                    self.s.onCompleted()
                    self.s = Subject()
                    self.observer.onNext(
                        AddRef(self.s, self.refCountDisposable))

            if newWindow:
                self.createTimer(newId)

        def onError(self, exception):
            with self.gate:
                self.s.onError(exception)
                self.observer.onError(exception)
                self.dispose()

        def onCompleted(self):
            with self.gate:
                self.s.onCompleted()
                self.observer.onCompleted()
                self.dispose()
Example #7
0
  class Sink(rx.linq.sink.Sink):
    def __init__(self, parent, observer, cancel):
      super(GroupBy.Sink, self).__init__(observer, cancel)
      self.parent = parent
      self.map = {}
      self.null = None

    def onNext(self, value):
      key = None

      try:
        key = self.parent.keySelector(value)
      except Exception as e:
        self.onError(e)
        return

      fireNewMapEntry = False
      writer = None

      try:
        if key == None:
          if self.null == None:
            self.null = Subject()
            fireNewMapEntry = True

          writer = self.null
        else:
          if key in self.map:
            writer = self.map[key]
          else:
            writer = Subject()
            self.map[key] = writer
            fireNewMapEntry = True
      except Exception as e:
        self.onError(e)
        return

      if fireNewMapEntry:
        group = GroupObservable(key, writer, self.parent.refCountDisposable)
        self.observer.onNext(group)

      element = None

      try:
        element = self.parent.elementSelector(value)
      except Exception as e:
        self.onError(e)
      else:
        writer.onNext(element)

    def onError(self, exception):
      if self.null != None:
        self.null.onError(exception)

      for x in self.map.values():
        x.onError(exception)

      self.observer.onError(exception)
      self.dispose()

    def onCompleted(self):
      if self.null != None:
        self.null.onCompleted()

      for x in self.map.values():
        x.onCompleted()

      self.observer.onCompleted()
      self.dispose()