Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在不增加延迟的情况下为monix中的每个任务添加固定延迟_Scala_Apache Kafka_Kafka Consumer Api_Apache Kafka Streams_Monix - Fatal编程技术网

Scala 如何在不增加延迟的情况下为monix中的每个任务添加固定延迟

Scala 如何在不增加延迟的情况下为monix中的每个任务添加固定延迟,scala,apache-kafka,kafka-consumer-api,apache-kafka-streams,monix,Scala,Apache Kafka,Kafka Consumer Api,Apache Kafka Streams,Monix,我正在使用monix使用卡夫卡的消息 我想在从主题中读取消息10秒后处理该消息 10秒-分钟的延迟不应阻止读取更多消息 我尝试使用下面的代码测试这种行为,使用Task.delayExecution延迟10秒 我还尝试了Observable.delayOnExecution和Observable.delayonext import monix.eval.Task import monix.reactive.Observable object TestApp extends App { imp

我正在使用monix使用卡夫卡的消息

我想在从主题中读取消息10秒后处理该消息

10秒-分钟的延迟不应阻止读取更多消息

我尝试使用下面的代码测试这种行为,使用Task.delayExecution延迟10秒

我还尝试了
Observable.delayOnExecution
Observable.delayonext

import monix.eval.Task
import monix.reactive.Observable

object TestApp extends App {
  import java.util.Date
  case class SomeClass(
                        value: Int, consumingDate: Date,
                        handlerExecutionDate: Date = null
                      )
  import scala.concurrent.duration._
  import scala.concurrent.Await
  import monix.execution.Scheduler.Implicits.global

  val res = Observable.fromIterable((1 to 100).map(i => SomeClass(value = i, consumingDate = new Date)))
    .mapEval(i =>
      Task.delay(
        SomeClass(
          value = i.value,
          consumingDate = i.consumingDate
        )
      ).delayExecution(10 seconds)
    )
    .foreachL{ x =>
      val r = SomeClass(
        x.value,
        x.consumingDate,
        new Date()
      )
      println(r)
    }.runToFuture
  Await.result(res, 100.seconds)
}

但是上面的代码为每条消息增加了延迟。第一条消息延迟10秒,但第二条消息延迟20秒,第三条消息延迟30秒,依此类推

使用monix可以做类似的事情吗

我正在考虑其他替代基于monix的解决方案,比如使用内存队列。消费者将继续排队,直到达到其限制,然后

更新:

我使用
Task.eval().restartutil()找到了一个解决方案

添加下面的代码

package com.agoda.cusco.campaign.data.collector.consumer

import monix.eval.Task
import monix.reactive.Observable

object TestApp extends App {
  import java.util.Date
  case class SomeClass(
                        value: Int, consumingDate: Date,
                        handlerExecutionDate: Date = null
                      )
  import scala.concurrent.duration._
  import scala.concurrent.Await
  import monix.execution.Scheduler.Implicits.global

  val res = Observable.fromIterable((1 to 100).map(i => SomeClass(value = i, consumingDate = new Date(System.currentTimeMillis + i*100))))
    .mapEval(message =>
      Task.eval(new Date()).restartUntil(currentTime => (currentTime.getSeconds - message.consumingDate.getSeconds) > 10).map(_ => message)
    )
    .foreachL{ x =>
      val r = SomeClass(
        x.value,
        x.consumingDate,
        new Date()
      )
      println(r)
    }.runToFuture
  Await.result(res, 100.seconds)
}
我不完全确定它是否是理想的解决方案,因为它似乎正在进行活动CPU计算以使其工作


希望检查是否有更好的替代方案。

无法重现您的问题。我试着运行你的代码,它每10秒打印一行日期和时间,你确定你有如此多的延迟吗?是的,你是对的,打印的差异实际上是10秒。但是它仍然在增加延迟,因为事件/消息都是在
Observable.fromIterable(1到100)
中同时生成的,但是每个消息的打印都有10秒的延迟。我将更新代码,使其更清楚地表示问题。如果出于技术原因,听起来像是设计问题。如果这是一个产品需求,那么我想这是一个解决方案。在卡夫卡的记忆中排队通常是一种反模式。每个分区都是一个队列。消费者应该尽其所能消费。否则,需要编写逻辑来处理缓冲区溢出,在实例崩溃或重新启动时丢失内存中的消息。通过手动偏移提交,您可以克服邮件丢失的问题。实时处理通常需要在缓冲区溢出时丢弃消息,当处理速度跟不上传入速率时,必须丢弃消息。