如果下游仍在处理前一条消息,则需要将所有传入消息从上游放到下游。我试图通过限制缓冲区来做到这一点,但没有成功。我该如何实现?
这是我简单的例子
import akka.actor.{Actor, ActorSystem, Props}
import akka.stream.{ActorMaterializer, OverflowStrategy}
import akka.stream.scaladsl.{Flow, Sink, Source}
import scala.concurrent.duration._
object Test extends App {
implicit val system = ActorSystem("System")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val ec = system.dispatcher
val (actor, actorSource) = Source.actorRef[Int](bufferSize = 0, OverflowStrategy.dropBuffer).preMaterialize()
class ActualScheduledActor extends Actor {
var idx: Int = 0
override def receive: Receive = {
case _: Int =>
idx = idx + 1
if (idx < 6) {
println(s"sending $idx")
actor ! idx
}
}
}
val flow = Flow[Int].map { v =>
println(s"$v: Going to sleep.")
Thread.sleep(5000)
println(s"$v: Awake.")
v
}
val scheduledActor = system.actorOf(Props(new ActualScheduledActor))
system.scheduler.schedule(0.second, 1.second, scheduledActor, 0)
actorSource
.buffer(1, OverflowStrategy.dropBuffer)
.via(flow)
.runWith(Sink.ignore)
}
在此示例中,我使用ActualScheduledActor只是为了说明消息并未丢失并且似乎已被缓冲。这是输出:
sending 1
1: Going to sleep.
sending 2
sending 3
sending 4
sending 5
1: Awake.
2: Going to sleep.
2: Awake.
3: Going to sleep.
3: Awake.
4: Going to sleep.
4: Awake.
5: Going to sleep.
5: Awake.
答案 0 :(得分:0)
它确实会删除邮件,您只是没有发送足够的邮件。
请根据您的要求修改此代码。
object AkkaStreamDropMessage extends App {
import akka.actor.{Actor, ActorSystem, Props}
import akka.stream.OverflowStrategy
import akka.stream.scaladsl.{Flow, Sink, Source}
import scala.concurrent.duration._
implicit val system = ActorSystem("System")
implicit val materializer: ActorMaterializer = ActorMaterializer()
implicit val ec = system.dispatcher
val (actor, actorSource) = Source
.actorRef[Int](bufferSize = 0, OverflowStrategy.dropBuffer)
.preMaterialize()
class ActualScheduledActor extends Actor {
var idx: Int = 0
override def receive: Receive = {
case _: Int =>
idx = idx + 1
if (idx < 600) {
// println(s"sending $idx")
actor ! idx
}
}
}
val flow = Flow[Int].map { v =>
println(s"GOT: $v")
Thread.sleep(100)
v
}
val scheduledActor = system.actorOf(Props(new ActualScheduledActor))
system.scheduler.schedule(0.second, 50.millis, scheduledActor, 0)
actorSource
.buffer(1, OverflowStrategy.dropBuffer)
.via(flow)
.runWith(Sink.ignore)
}
它最终停止接收序列号
GOT: 34
GOT: 35
GOT: 36
GOT: 37
GOT: 38
GOT: 39
GOT: 49
在我的运行中,它从600个元素中删除了大约300个元素。
我认为(但我可能错了),它与为每个阶段定义的其他内部缓冲区有关,因此必须在实际的“丢弃”可见之前填充它们。