0

I'm trying to attach a reactivestream subscriber to an akka source.

My source seems to work fine with a simple sink (like a foreach) - but if I put in a real sink, made from a subscriber, I don't get anything.

My context is:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import org.reactivestreams.{Subscriber, Subscription}

implicit val system =  ActorSystem.create("test")
implicit val materializer = ActorMaterializer.create(system)

class PrintSubscriber extends Subscriber[String] {
  override def onError(t: Throwable): Unit = {}
  override def onSubscribe(s: Subscription): Unit = {}
  override def onComplete(): Unit = {}
  override def onNext(t: String): Unit = {
    println(t)
  }
}

and my test case is:

val subscriber = new PrintSubscriber()
val sink = Sink.fromSubscriber(subscriber)

val source2 = Source.fromIterator(() => Iterator("aaa", "bbb", "ccc"))
val source1 = Source.fromIterator(() => Iterator("xxx", "yyy", "zzz"))
source1.to(sink).run()(materializer)
source2.runForeach(println)

I get output:

aaa
bbb
ccc

Why don't I get xxx, yyy, and zzz?

Nathan Kronenfeld
  • 473
  • 1
  • 5
  • 14

1 Answers1

2

Citing the Reactive Streams specs for the Subscriber below:

Will receive call to onSubscribe(Subscription) once after passing an instance of Subscriber to Publisher.subscribe(Subscriber). No further notifications will be received until Subscription.request(long) is called.

The smallest change you can make to see some items flowing through to your subscriber is

override def onSubscribe(s: Subscription): Unit = {
  s.request(3)
}

However, keep in mind this won't make it fully compliant to the Reactive Streams specs. It being not-so-easy to implement is the main reason behind higher level toolkits like Akka-Streams itself.

Stefano Bonetti
  • 8,973
  • 1
  • 25
  • 44