Akka 每N分钟运行一次,或者如果项目与平均值不同

Akka 每N分钟运行一次,或者如果项目与平均值不同,akka,akka-stream,akka.net,Akka,Akka Stream,Akka.net,我有一个演员,他接收天气状况,然后(通过使用OfferAsync)将其推送到源代码。目前,它被设置为为为接收到的每个项目运行(它将其存储到数据库) 公共类StoreConditionsActor:ReceiveActor { 公共存储条件提供程序(ItemTemperatureDataProvider temperatureDataProvider) { var materializer=Context.materializer(); var source=source.Queue(10,Ove

我有一个演员,他接收
天气状况
,然后(通过使用
OfferAsync
)将其推送到
源代码
。目前,它被设置为为为接收到的每个项目运行(它将其存储到数据库)

公共类StoreConditionsActor:ReceiveActor
{
公共存储条件提供程序(ItemTemperatureDataProvider temperatureDataProvider)
{
var materializer=Context.materializer();
var source=source.Queue(10,OverflowStrategy.DropTail);
变量图=源
.To(Sink.ForEach(条件=>temperatureDataProvider.Store(条件)))
.Run(物化器);
接收(i=>
{
图1.OfferAsync(i);
});
}
}
我希望达到的目标是:

  • 仅每N分钟运行一次,并存储在此N分钟时间窗口中收到的所有项目的
    WeatherConditions
    平均值
  • 如果收到的物品符合特定条件(即,物品温度比前一个物品的温度高30%),尽管在时间窗口中“隐藏”,但仍运行该物品

  • 我一直在尝试将种子、缓冲区、节流阀混为一谈,但两者都不起作用(我是Akka/Akka Streams的新手,所以我可能缺少一些基本的东西)

    这个答案使用了Akka Streams和Scala,但可能会启发您的Akka.NET解决方案

    groupedWithin
    方法可以满足您的第一个要求:

    val队列=
    Source.queue[Int](10,OverflowStrategy.dropTail)
    .groupedWithin(10,1秒)
    .map(group=>group.sum/group.size)
    .toMat(Sink.foreach(println))(Keep.left)
    .run()
    资料来源(1至10000)
    .节气门(10,1秒)
    .mapsync(1)(queue.offer()
    .runWith(Sink.ignore)
    
    在上面的示例中,
    SourceQueue
    每秒最多提供10个整数,它将传入元素分组到一秒钟的束中,并计算每个束的相应平均值

    至于第二个需求,您可以使用
    滑动
    将一个元素与前一个元素进行比较。以下示例仅当某个图元至少比前一个图元大30%时,才将其传递到下游:

    val-source:source[Int,z]=???
    来源
    .滑动(2,1)
    .收集{
    如果b>=1.3*a=>b,则案例顺序(a,b)
    }
    .runForeach(println)
    
    此答案使用Akka Streams和Scala,但它可能会启发您的Akka.NET解决方案

    groupedWithin
    方法可以满足您的第一个要求:

    val队列=
    Source.queue[Int](10,OverflowStrategy.dropTail)
    .groupedWithin(10,1秒)
    .map(group=>group.sum/group.size)
    .toMat(Sink.foreach(println))(Keep.left)
    .run()
    资料来源(1至10000)
    .节气门(10,1秒)
    .mapsync(1)(queue.offer()
    .runWith(Sink.ignore)
    
    在上面的示例中,
    SourceQueue
    每秒最多提供10个整数,它将传入元素分组到一秒钟的束中,并计算每个束的相应平均值

    至于第二个需求,您可以使用
    滑动
    将一个元素与前一个元素进行比较。以下示例仅当某个图元至少比前一个图元大30%时,才将其传递到下游:

    val-source:source[Int,z]=???
    来源
    .滑动(2,1)
    .收集{
    如果b>=1.3*a=>b,则案例顺序(a,b)
    }
    .runForeach(println)
    
    不错的解决方案。对于第一个需求,我不明白为什么需要
    SourceQueue
    。为什么不仅仅是
    节流阀
    +
    分组
    ?伙计,这个
    Akka
    东西很强大:)文档(至少
    .net
    一个)可能会更好不过。。。谢谢很好的解决方案。对于第一个需求,我不明白为什么需要
    SourceQueue
    。为什么不仅仅是
    节流阀
    +
    分组
    ?伙计,这个
    Akka
    东西很强大:)文档(至少
    .net
    一个)可能会更好不过。。。谢谢
    public class StoreConditionsActor : ReceiveActor
    {
        public StoreConditionsActor(ITemperatureDataProvider temperatureDataProvider)
        {
            var materializer = Context.Materializer();
            var source = Source.Queue<WeatherConditions>(10, OverflowStrategy.DropTail);
    
            var graph = source
                .To(Sink.ForEach<WeatherConditions>(conditions => temperatureDataProvider.Store(conditions)))
                .Run(materializer);
    
            Receive<WeatherConditions>(i =>
            {
                graph.OfferAsync(i);
            });
        }
    }