class EnumeratingSink(Observer): def __init__(self, onNext, done): self.onNextAction = onNext self.doneAction = done self.index = 0 self.stopped = Atomic(False) self.exception = None def onNext(self, value): if not self.stopped.value: try: self.onNextAction(value, self.index) self.index += 1 except Exception as e: self.onError(e) def onError(self, exception): if not self.stopped.exchange(True): self.exception = exception self.doneAction() def onCompleted(self): if not self.stopped.exchange(True): self.doneAction()
class Sink(Disposable): """Base class for implementation of query operators, providing a lightweight sink that can be disposed to mute the outgoing observer.""" def __init__(self, observer, cancel): super(Sink, self).__init__() self.observer = observer self.cancel = Atomic(cancel) def dispose(self): self.observer = NoopObserver.instance cancel = self.cancel.exchange(None) if cancel != None: cancel.dispose() class Forewarder(Observer): def __init__(self, foreward): self.foreward = foreward def onNext(self, value): self.foreward.observer.onNext(value) def onError(self, exception): self.foreward.observer.onError(exception) self.foreward.dispose() def onCompleted(self): self.foreward.observer.onCompleted() self.foreward.dispose() def getForewarder(self): return self.Forewarder(self)
class InnerDisposable(Disposable): def __init__(self, parent): self.parent = Atomic(parent) def dispose(self): parent = self.parent.exchange(None) if parent != None: parent.release()
class ObserverBase(Cancelable, Observer): """Abstract base class for implementations of the IObserver interface. This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages.""" def __init__(self): super(ObserverBase, self).__init__() self.isStopped = Atomic(False, self.lock) def onNext(self, value): with self.lock: if self.isStopped.value: return self.onNextCore(value) def onError(self, exception): if not self.isStopped.exchange(True): self.onErrorCore(exception) def onCompleted(self): if not self.isStopped.exchange(True): self.onCompletedCore() def dispose(self): self.isStopped.value = True def fail(self, exception): if self.isStopped.exchange(True): # isStopped was already true return False else: self.onErrorCore(exception) return True def onNextCore(self, value): raise NotImplementedError() def onErrorCore(self, exception): raise NotImplementedError() def onCompletedCore(self): raise NotImplementedError()
class Subscription(Disposable): def __init__(self, subject, observer): self.subject = subject self.observer = Atomic(observer) def dispose(self): old = self.observer.exchange(None) if old != None: self.subject.unsubscribe(old) self.subject = None
class ObserveOnObserver(ScheduledObserver): def __init__(self, scheduler, observer, cancel): super(ObserveOnObserver, self).__init__(scheduler, observer) self.cancel = Atomic(cancel, self.lock) def onNextCore(self, value): super(ObserveOnObserver, self).onNextCore(value) self.ensureActive() def onErrorCore(self, exception): super(ObserveOnObserver, self).onErrorCore(exception) self.ensureActive() def onCompletedCore(self): super(ObserveOnObserver, self).onCompletedCore() self.ensureActive() def dispose(self): super(ObserveOnObserver, self).dispose() old = self.cancel.exchange(None) if old != None: old.dispose()
class Subject(Observable, Observer): def __init__(self): super(Subject, self).__init__() self.isDisposed = False self.isStopped = False self.exception = None self.observer = Atomic(NoopObserver.instance) def onCompleted(self): old = None new = DoneObserver.completed while True: old = self.observer.value if old is DoneObserver.completed or isinstance(old, DoneObserver): break current = self.observer.compareExchange(new, old) if old is current: break old.onCompleted() def onError(self, exception): old = None new = DoneObserver(exception) while True: old = self.observer.value if old is DoneObserver.completed or isinstance(old, DoneObserver): break current = self.observer.compareExchange(new, old) if old is current: break old.onError(exception) def onNext(self, value): self.observer.value.onNext(value) class Subscription(Disposable): def __init__(self, subject, observer): self.subject = subject self.observer = Atomic(observer) def dispose(self): old = self.observer.exchange(None) if old != None: self.subject.unsubscribe(old) self.subject = None 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) def unsubscribe(self, observer): old = None new = None while True: old = self.observer.value if old is DisposedObserver.instance or isinstance( old, DoneObserver): return if isinstance(old, ListObserver): new = old.remove(observer) elif observer is not old: return else: new = NoopObserver.instance current = self.observer.compareExchange(new, old) if old is current: return def dispose(self): self.observer.exchange(NoopObserver.instance) @staticmethod def create(observer, observable): return AnonymousSubject(observer, observable) @staticmethod def synchronize(subject, scheduler=None): if scheduler == None: return AnonymousSubject(Observer.synchronize(subject), subject) else: return AnonymousSubject(Observer.synchronize(subject), subject.observeOn(scheduler))
class Subject(Observable, Observer): def __init__(self): super(Subject, self).__init__() self.isDisposed = False self.isStopped = False self.exception = None self.observer = Atomic(NoopObserver.instance) def onCompleted(self): old = None new = DoneObserver.completed while True: old = self.observer.value if old is DoneObserver.completed or isinstance(old, DoneObserver): break current = self.observer.compareExchange(new, old) if old is current: break old.onCompleted() def onError(self, exception): old = None new = DoneObserver(exception) while True: old = self.observer.value if old is DoneObserver.completed or isinstance(old, DoneObserver): break current = self.observer.compareExchange(new, old) if old is current: break old.onError(exception) def onNext(self, value): self.observer.value.onNext(value) class Subscription(Disposable): def __init__(self, subject, observer): self.subject = subject self.observer = Atomic(observer) def dispose(self): old = self.observer.exchange(None) if old != None: self.subject.unsubscribe(old) self.subject = None 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) def unsubscribe(self, observer): old = None new = None while True: old = self.observer.value if old is DisposedObserver.instance or isinstance(old, DoneObserver): return if isinstance(old, ListObserver): new = old.remove(observer) elif observer is not old: return else: new = NoopObserver.instance current = self.observer.compareExchange(new, old) if old is current: return def dispose(self): self.observer.exchange(NoopObserver.instance) @staticmethod def create(observer, observable): return AnonymousSubject(observer, observable) @staticmethod def synchronize(subject, scheduler=None): if scheduler == None: return AnonymousSubject(Observer.synchronize(subject), subject) else: return AnonymousSubject(Observer.synchronize(subject), subject.observeOn(scheduler))