monix.reactive.observers.Subscriber Scala Examples
The following examples show how to use monix.reactive.observers.Subscriber.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: ObservablesPartitioner.scala From gbf-raidfinder with MIT License | 5 votes |
package walfie.gbf.raidfinder.util import akka.agent.Agent import monix.execution.{Ack, Cancelable, Scheduler} import monix.reactive._ import monix.reactive.observables.GroupedObservable import monix.reactive.observers.Subscriber import monix.reactive.subjects.PublishSubject import scala.concurrent.{ExecutionContext, Future} trait ObservablesPartitioner[K, V] { def getObservable(key: K): Observable[V] } object CachedObservablesPartitioner { def fromUngroupedObservable[K, InputV, OutputV]( observable: Observable[InputV], cacheSizePerKey: Int, keySelector: InputV => K, mappingFunction: InputV => OutputV )(implicit scheduler: Scheduler): (CachedObservablesPartitioner[K, InputV, OutputV], Cancelable) = { val partitioner = new CachedObservablesPartitioner[K, InputV, OutputV](cacheSizePerKey, mappingFunction) val cancelable = observable.groupBy(keySelector).subscribe(partitioner) (partitioner, cancelable) } } class CachedObservablesPartitioner[K, InputV, OutputV]( cacheSizePerKey: Int, mappingFunction: InputV => OutputV )(implicit ec: ExecutionContext) extends Observer[GroupedObservable[K, InputV]] with ObservablesPartitioner[K, OutputV] { private val observablesByKey = Agent[Map[K, Observable[OutputV]]](Map.empty) private val incomingKeys = PublishSubject[K]() def onComplete(): Unit = { incomingKeys.onComplete() } def onError(e: Throwable): Unit = { System.err.println(e) // TODO: Better logging? incomingKeys.onError(e) } def getObservable(key: K): Observable[OutputV] = { observablesByKey.get.getOrElse( key, incomingKeys.findF(_ == key).flatMap(_ => getObservable(key)) ) } }
Example 2
Source File: Implicits.scala From matcher with MIT License | 5 votes |
package com.wavesplatform.dex.util import monix.execution.{Ack, Cancelable} import monix.reactive.observers.Subscriber import monix.reactive.subjects.Subject import scala.concurrent.Future object Implicits { final implicit class SubjectOps(val self: Subject.type) extends AnyVal { def empty[T]: Subject[T, T] = new Subject[T, T] { override def size: Int = 0 override def unsafeSubscribeFn(subscriber: Subscriber[T]): Cancelable = Cancelable.empty override def onNext(elem: T): Future[Ack] = Future.successful(Ack.Stop) override def onError(ex: Throwable): Unit = {} override def onComplete(): Unit = {} } } }
Example 3
Source File: WatchServiceObservable.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.file.WatchEvent import monix.eval.Task import monix.execution.Ack.{ Continue, Stop } import monix.execution.atomic.Atomic import monix.execution.cancelables.SingleAssignCancelable import monix.execution.exceptions.APIContractViolationException import monix.execution.{ Callback, Cancelable, Scheduler } import monix.reactive.Observable import monix.reactive.observers.Subscriber import scala.concurrent.Future import scala.util.control.NonFatal abstract class WatchServiceObservable extends Observable[Array[WatchEvent[_]]] { def watchService: Option[WatchService] private[this] val wasSubscribed = Atomic(false) override def unsafeSubscribeFn(subscriber: Subscriber[Array[WatchEvent[_]]]): Cancelable = { if (wasSubscribed.getAndSet(true)) { subscriber.onError(APIContractViolationException(this.getClass.getName)) Cancelable.empty } else try startPolling(subscriber) catch { case NonFatal(e) => subscriber.onError(e) Cancelable.empty } } def init(subscriber: Subscriber[Array[WatchEvent[_]]]): Future[Unit] = Future.successful(()) private def startPolling(subscriber: Subscriber[Array[WatchEvent[_]]]): Cancelable = { import subscriber.scheduler val taskCallback = new Callback[Throwable, Array[WatchEvent[_]]]() { override def onSuccess(value: Array[WatchEvent[_]]): Unit = {} override def onError(ex: Throwable): Unit = { subscriber.onError(ex) } } val cancelable = Task .fromFuture(init(subscriber)) .flatMap { _ => loop(subscriber) } .executeWithOptions(_.enableAutoCancelableRunLoops) .runAsync(taskCallback) val extraCancelable = Cancelable(() => { cancelable.cancel() }) SingleAssignCancelable.plusOne(extraCancelable) } private def loop(subscriber: Subscriber[Array[WatchEvent[_]]])(implicit scheduler: Scheduler): Task[Array[WatchEvent[_]]] = { import collection.JavaConverters._ watchService.map { ws => ws.take() .doOnCancel(Task.defer(ws.close())) .flatMap { key => val events = key.pollEvents().asScala.toArray key.reset() Task.fromFuture(subscriber.onNext(events)).flatMap { case Continue => loop(subscriber) case Stop => emptyTask } } } }.getOrElse(emptyTask) private val emptyTask = Task.create[Array[WatchEvent[_]]]((_, _) => Cancelable.empty) }
Example 4
Source File: AsyncSocketChannelObservable.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio.tcp import java.net.InetSocketAddress import monix.execution.Callback import monix.nio._ import monix.reactive.observers.Subscriber import scala.concurrent.Promise final class AsyncSocketChannelObservable private[tcp] ( host: String, port: Int, override val bufferSize: Int = 256 * 1024) extends AsyncChannelObservable { private[this] val connectedSignal = Promise[Unit]() private[this] var taskSocketChannel: Option[TaskSocketChannel] = None private[this] var closeOnComplete = true private[tcp] def this(tsc: TaskSocketChannel, buffSize: Int, closeWhenDone: Boolean) = { this("", 0, buffSize) this.taskSocketChannel = Option(tsc) this.closeOnComplete = closeWhenDone } override lazy val channel = taskSocketChannel.map(asc => asyncChannelWrapper(asc, closeOnComplete)) override def init(subscriber: Subscriber[Array[Byte]]) = { import subscriber.scheduler if (taskSocketChannel.isDefined) { connectedSignal.success(()) } else { val connectCallback = new Callback[Throwable, Unit]() { override def onSuccess(value: Unit): Unit = { connectedSignal.success(()) } override def onError(ex: Throwable): Unit = { connectedSignal.failure(ex) closeChannel() subscriber.onError(ex) } } taskSocketChannel = Option(TaskSocketChannel()) taskSocketChannel.foreach(_.connect(new InetSocketAddress(host, port)).runAsync(connectCallback)) } connectedSignal.future } }
Example 5
Source File: AsyncChannelConsumer.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.ByteBuffer import monix.execution.Ack.{ Continue, Stop } import monix.execution.{ Ack, Callback, Cancelable, Scheduler } import monix.execution.atomic.Atomic import monix.execution.cancelables.{ AssignableCancelable, SingleAssignCancelable } import monix.reactive.Consumer import monix.reactive.observers.Subscriber import scala.concurrent.{ Future, Promise } import scala.util.control.NonFatal private[nio] abstract class AsyncChannelConsumer extends Consumer[Array[Byte], Long] { def channel: Option[AsyncChannel] def withInitialPosition: Long = 0L def init(subscriber: AsyncChannelSubscriber): Future[Unit] = Future.successful(()) class AsyncChannelSubscriber(consumerCallback: Callback[Throwable, Long])(implicit val scheduler: Scheduler) extends Subscriber[Array[Byte]] { self => private[this] lazy val initFuture = init(self) private[this] val callbackCalled = Atomic(false) private[this] var position = withInitialPosition override def onNext(elem: Array[Byte]): Future[Ack] = { def write(): Future[Ack] = { val promise = Promise[Ack]() channel.foreach { sc => try { sc .write(ByteBuffer.wrap(elem), position) .runAsync( new Callback[Throwable, Int] { override def onError(exc: Throwable) = { closeChannel() sendError(exc) promise.success(Stop) } override def onSuccess(result: Int): Unit = { position += result promise.success(Continue) } }) } catch { case NonFatal(ex) => sendError(ex) promise.success(Stop) } } promise.future } if (initFuture.value.isEmpty) { initFuture.flatMap(_ => write()) } else { write() } } override def onComplete(): Unit = { channel.collect { case sc if sc.closeOnComplete => closeChannel() } if (callbackCalled.compareAndSet(expect = false, update = true)) consumerCallback.onSuccess(position) } override def onError(ex: Throwable): Unit = { closeChannel() sendError(ex) } private[nio] def onCancel(): Unit = { callbackCalled.set(true) closeChannel() } private[nio] def sendError(t: Throwable) = if (callbackCalled.compareAndSet(expect = false, update = true)) { scheduler.execute(new Runnable { def run() = consumerCallback.onError(t) }) } private[nio] final def closeChannel()(implicit scheduler: Scheduler) = channel.foreach(_.close().runToFuture) } override def createSubscriber(cb: Callback[Throwable, Long], s: Scheduler): (Subscriber[Array[Byte]], AssignableCancelable) = { val out = new AsyncChannelSubscriber(cb)(s) val extraCancelable = Cancelable(() => out.onCancel()) val conn = SingleAssignCancelable.plusOne(extraCancelable) (out, conn) } }
Example 6
Source File: AsyncChannelObservable.scala From monix-nio with Apache License 2.0 | 5 votes |
package monix.nio import java.nio.ByteBuffer import monix.eval.Task import monix.execution.Ack.{ Continue, Stop } import monix.execution.{ Callback, Cancelable, Scheduler } import monix.execution.atomic.Atomic import monix.execution.cancelables.SingleAssignCancelable import monix.execution.exceptions.APIContractViolationException import monix.nio.internal.{ Bytes, EmptyBytes, NonEmptyBytes } import monix.reactive.Observable import monix.reactive.observers.Subscriber import scala.concurrent.Future import scala.util.control.NonFatal private[nio] abstract class AsyncChannelObservable extends Observable[Array[Byte]] { def bufferSize: Int def channel: Option[AsyncChannel] def init(subscriber: Subscriber[Array[Byte]]): Future[Unit] = Future.successful(()) private[this] val wasSubscribed = Atomic(false) override def unsafeSubscribeFn(subscriber: Subscriber[Array[Byte]]): Cancelable = { import subscriber.scheduler if (wasSubscribed.getAndSet(true)) { subscriber.onError(APIContractViolationException(this.getClass.getName)) Cancelable.empty } else try startReading(subscriber) catch { case NonFatal(e) => subscriber.onError(e) closeChannel() Cancelable.empty } } private def startReading(subscriber: Subscriber[Array[Byte]]): Cancelable = { import subscriber.scheduler val taskCallback = new Callback[Throwable, Array[Byte]]() { override def onSuccess(value: Array[Byte]): Unit = { channel.collect { case sc if sc.closeOnComplete => closeChannel() } } override def onError(ex: Throwable): Unit = { closeChannel() subscriber.onError(ex) } } val cancelable = Task .fromFuture(init(subscriber)) .flatMap { _ => loop(subscriber, 0) } .executeWithOptions(_.enableAutoCancelableRunLoops) .runAsync(taskCallback) val extraCancelable = Cancelable(() => { cancelable.cancel() closeChannel() }) SingleAssignCancelable.plusOne(extraCancelable) } private[this] val buffer = ByteBuffer.allocate(bufferSize) private def loop(subscriber: Subscriber[Array[Byte]], position: Long)(implicit scheduler: Scheduler): Task[Array[Byte]] = { buffer.clear() channel.map { ch => ch .read(buffer, position) .doOnCancel(Task.defer(ch.close())) .flatMap { result => val bytes = Bytes(buffer, result) bytes match { case EmptyBytes => subscriber.onComplete() Task.now(Bytes.emptyBytes) case NonEmptyBytes(arr) => Task.fromFuture(subscriber.onNext(arr)).flatMap { case Continue => loop(subscriber, position + result) case Stop => Task.now(Bytes.emptyBytes) } } } }.getOrElse(Task.now(Bytes.emptyBytes)) } private[nio] final def closeChannel()(implicit scheduler: Scheduler) = channel.foreach(_.close().runToFuture) }
Example 7
Source File: UserEventProducer.scala From frees-rpc-workshop with Apache License 2.0 | 5 votes |
package scalaexchange package datagenerator import com.fortysevendeg.scalacheck.datetime.GenDateTime import com.fortysevendeg.scalacheck.datetime.instances.joda.jodaForPeriod import monix.execution.Cancelable import monix.reactive.Observable import monix.reactive.observers.Subscriber import org.joda.time.{DateTime, Period} import scala.concurrent.duration.FiniteDuration class UserEventProducer(interval: FiniteDuration) extends Observable[UserEvent] { override def unsafeSubscribeFn(subscriber: Subscriber[UserEvent]): Cancelable = { val userEventRandom: Observable[UserEvent] = Observable .fromStateAction(eventsGen)(Nil) .flatMap { a => Observable.now(a).delaySubscription(interval) } userEventRandom.drop(1).unsafeSubscribeFn(subscriber) } private[this] def eventsGen(initialState: List[UserEvent]): (UserEvent, List[UserEvent]) = { import org.scalacheck._ val dataGen: Arbitrary[UserEvent] = Arbitrary { import Gen._ for { id <- choose(1, 100) eventType <- Gen.oneOf(List(ProcessedCheckout, UnprocessedCheckout, Login)) date <- GenDateTime.genDateTimeWithinRange(DateTime.parse("2017-12-01"), Period.days(22)) } yield UserEvent(id, eventType, date.toString()) } val newEvent: UserEvent = dataGen.arbitrary.sample .getOrElse(throw DataGenerationException("Exception creating new random event")) (newEvent, initialState :+ newEvent) } }
Example 8
Source File: DataConsumer.scala From monix-sample with Apache License 2.0 | 5 votes |
package client import monix.execution.Cancelable import monix.reactive.Observable import monix.reactive.OverflowStrategy.DropNew import monix.reactive.observers.Subscriber import org.scalajs.dom import shared.models.{Event, OverflowEvent, Signal} import scala.concurrent.duration.FiniteDuration import scala.scalajs.js.Dynamic.global final class DataConsumer(interval: FiniteDuration, seed: Long, doBackPressure: Boolean) extends Observable[Event] { override def unsafeSubscribeFn(subscriber: Subscriber[Event]): Cancelable = { val host = dom.window.location.host val protocol = if (dom.document.location.protocol == "https:") "wss:" else "ws:" val source = if (doBackPressure) { val url = s"$protocol//$host/back-pressured-stream?periodMillis=${interval.toMillis}&seed=$seed" BackPressuredWebSocketClient(url) } else { val url = s"$protocol//$host/simple-stream?periodMillis=${interval.toMillis}&seed=$seed" SimpleWebSocketClient(url, DropNew(1000)) } source .collect { case IsEvent(e) => e } .unsafeSubscribeFn(subscriber) } object IsEvent { def unapply(message: String) = { val json = global.JSON.parse(message) json.event.asInstanceOf[String] match { case "point" => Some(Signal( value = json.value.asInstanceOf[Number].doubleValue(), timestamp = json.timestamp.asInstanceOf[Number].longValue() )) case "overflow" => Some(OverflowEvent( dropped = json.dropped.asInstanceOf[Number].longValue(), timestamp = json.timestamp.asInstanceOf[Number].longValue() )) case "error" => val errorType = json.`type`.asInstanceOf[String] val message = json.message.asInstanceOf[String] throw new BackPressuredWebSocketClient.Exception( s"Server-side error throw - $errorType: $message") case _ => None } } } }
Example 9
Source File: DataProducer.scala From monix-sample with Apache License 2.0 | 5 votes |
package engine import monix.execution.Cancelable import monix.reactive.Observable import monix.reactive.observers.Subscriber import shared.models.Signal import util.Random import scala.concurrent.duration._ final class DataProducer(interval: FiniteDuration, seed: Long) extends Observable[Signal] { override def unsafeSubscribeFn(subscriber: Subscriber[Signal]): Cancelable = { import subscriber.{scheduler => s} val random = Observable .fromStateAction(Random.intInRange(-20, 20))(s.currentTimeMillis() + seed) .flatMap { x => Observable.now(x).delaySubscription(interval) } val generator = random.scan(Signal(0, s.currentTimeMillis())) { case (Signal(value, _), rnd) => Signal(value + rnd, s.currentTimeMillis()) } generator .drop(1) .unsafeSubscribeFn(subscriber) } }
Example 10
Source File: TakeWhileInclusive.scala From tofu with Apache License 2.0 | 5 votes |
package tofu.observable import monix.execution.Ack import monix.execution.Ack.Stop import monix.reactive.observers.Subscriber import scala.concurrent.Future import scala.util.control.NonFatal //shameless copy of monix.reactive.internal.operators.TakeByPredicateOperator private[observable] final case class TakeWhileInclusive[A](p: A => Boolean, out: Subscriber[A]) extends Subscriber[A] { implicit val scheduler = out.scheduler private[this] var isActive = true def onNext(elem: A): Future[Ack] = { if (!isActive) Stop else { // Protects calls to user code from within an operator var streamError = true try { val isValid = p(elem) streamError = false if (isValid) out.onNext(elem) else { isActive = false out .onNext(elem) .map { _ => out.onComplete() Stop } } } catch { case NonFatal(ex) if streamError => onError(ex) Stop } } } def onComplete() = if (isActive) { isActive = false out.onComplete() } def onError(ex: Throwable) = if (isActive) { isActive = false out.onError(ex) } }
Example 11
Source File: GrpcMonix.scala From grpcmonix with MIT License | 5 votes |
package grpcmonix import com.google.common.util.concurrent.ListenableFuture import io.grpc.stub.StreamObserver import monix.eval.{Callback, Task} import monix.execution.Ack.{Continue, Stop} import monix.execution.{Ack, Scheduler} import monix.reactive.Observable import monix.reactive.observables.ObservableLike.{Operator, Transformer} import monix.reactive.observers.Subscriber import monix.reactive.subjects.PublishSubject import org.reactivestreams.{Subscriber => SubscriberR} import scalapb.grpc.Grpc import scala.concurrent.Future object GrpcMonix { type GrpcOperator[I, O] = StreamObserver[O] => StreamObserver[I] def guavaFutureToMonixTask[T](future: ListenableFuture[T]): Task[T] = Task.deferFuture { Grpc.guavaFuture2ScalaFuture(future) } def grpcOperatorToMonixOperator[I,O](grpcOperator: GrpcOperator[I,O]): Operator[I,O] = { outputSubsriber: Subscriber[O] => val outputObserver: StreamObserver[O] = monixSubscriberToGrpcObserver(outputSubsriber) val inputObserver: StreamObserver[I] = grpcOperator(outputObserver) grpcObserverToMonixSubscriber(inputObserver, outputSubsriber.scheduler) } def monixSubscriberToGrpcObserver[T](subscriber: Subscriber[T]): StreamObserver[T] = new StreamObserver[T] { override def onError(t: Throwable): Unit = subscriber.onError(t) override def onCompleted(): Unit = subscriber.onComplete() override def onNext(value: T): Unit = subscriber.onNext(value) } def reactiveSubscriberToGrpcObserver[T](subscriber: SubscriberR[_ >: T]): StreamObserver[T] = new StreamObserver[T] { override def onError(t: Throwable): Unit = subscriber.onError(t) override def onCompleted(): Unit = subscriber.onComplete() override def onNext(value: T): Unit = subscriber.onNext(value) } def grpcObserverToMonixSubscriber[T](observer: StreamObserver[T], s: Scheduler): Subscriber[T] = new Subscriber[T] { override implicit def scheduler: Scheduler = s override def onError(t: Throwable): Unit = observer.onError(t) override def onComplete(): Unit = observer.onCompleted() override def onNext(value: T): Future[Ack] = try { observer.onNext(value) Continue } catch { case t: Throwable => observer.onError(t) Stop } } def grpcObserverToMonixCallback[T](observer: StreamObserver[T]): Callback[T] = new Callback[T] { override def onError(t: Throwable): Unit = observer.onError(t) override def onSuccess(value: T): Unit = { observer.onNext(value) observer.onCompleted() } } def liftByGrpcOperator[I, O](observable: Observable[I], operator: GrpcOperator[I, O]): Observable[O] = observable.liftByOperator( grpcOperatorToMonixOperator(operator) ) def unliftByTransformer[I, O](transformer: Transformer[I, O], subscriber: Subscriber[O]): Subscriber[I] = new Subscriber[I] { private[this] val subject = PublishSubject[I]() subject.transform(transformer).subscribe(subscriber) override implicit def scheduler: Scheduler = subscriber.scheduler override def onError(t: Throwable): Unit = subject.onError(t) override def onComplete(): Unit = subject.onComplete() override def onNext(value: I): Future[Ack] = subject.onNext(value) } }