Akka Streams,如果完成处理一个元素到下一个处理开始之间的时间超时

时间:2018-04-11 17:41:13

标签: scala akka akka-stream

如果完成处理一个元素直到开始处理下一个元素之间的时间超过特定数量,我希望我的流失败。 当前的超时方法似乎都没有处理这种情况。我该怎么做?

1 个答案:

答案 0 :(得分:0)

这是我最接近的解决方案(试试here):

SplatResolver = Locator.CurrentMutable;
var customResolver = new FuncDependencyResolver((service, contract) =>
{
    IEnumerable<Object> services = null;
    services = SplatResolver.GetServices(service, contract);
    if (services == null || services.Count() == 0)
    {
        var svc = containerSI.GetInstance(service);
        if (svc != null)
        {
            services = new Object[] { svc };
        }
    }
    if (services == null || services.Count() == 0)
    {
        services = containerSI.GetAllInstances(service); // only applies services registered with .RegisterCollection()
    }
    return services;
}, (factory, service, contract) =>
{
    SplatResolver.Register(factory, service, contract);

    try
    {
        containerSI.Register(service, factory);
    }
    catch (Exception exc)
    {
        // certain services are registered multiple times by RxUI.  For now, ignore them.
        //ICreatesObservableForProperty
        Console.WriteLine(exc.ToString());
    }
});

Locator.Current = customResolver;

打印:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
import concurrent.duration._
import concurrent.Await
import concurrent.ExecutionContext.Implicits.global
import concurrent.Future

implicit class StreamTakeWithinTime[Out, Mat](src: Source[Out, Mat]) {
  def takeWithinTime(maxIdleTime: FiniteDuration): Source[Out, Mat] =
    src
      .map(Option.apply)
      .keepAlive(maxIdleTime, () => None)
      .takeWhile {
        case Some(_) => true
        case None    => false
      }
      .collect {
        case Some(x) => x
      }
}

implicit val actorSystem = ActorSystem("test")
implicit val actorMaterializer = ActorMaterializer()

var delay = 0
def tick = {
  delay += 500
  Thread.sleep(delay)
  "tick"
}

val maxIdleTime = 2.seconds

val pipeline = Source
  .fromIterator(() =>
    new Iterator[String] {
      override def hasNext: Boolean = true
      override def next(): String = tick
  })
  .map { s =>
    println("Long processing function...")
    Thread.sleep(3000)
    s
  }
  .takeWithinTime(maxIdleTime)

val res = Await.result(pipeline.runForeach(println), 30.seconds)
println("done")