指定任务fs2 streams Scala的处理时间
我正在尝试处理一些任务。 任务所需的时间可能因要素而异。例如,从队列中存储和获取元素1可能需要11秒,而元素2可能需要30秒 我已经尝试过使用计时器,但仍然得到entryTime=ExitTime 我想知道我错过了什么 以下是我尝试过的:指定任务fs2 streams Scala的处理时间,scala,timer,queue,scheduling,fs2,Scala,Timer,Queue,Scheduling,Fs2,我正在尝试处理一些任务。 任务所需的时间可能因要素而异。例如,从队列中存储和获取元素1可能需要11秒,而元素2可能需要30秒 我已经尝试过使用计时器,但仍然得到entryTime=ExitTime 我想知道我错过了什么 以下是我尝试过的: import cats.effect.{ExitCode, IO, IOApp, Timer} import fs2._ import fs2.concurrent.Queue import scala.concurrent.duration._ import
import cats.effect.{ExitCode, IO, IOApp, Timer}
import fs2._
import fs2.concurrent.Queue
import scala.concurrent.duration._
import scala.util.Random
class Tst(q1: Queue[IO, (Double, String, String)])(implicit timer: Timer[IO]) {
import core.Processing._
def storeInQueue: Stream[IO, Unit] = {
Stream(1, 2, 3)
.covary[IO]
.evalTap(n => IO.delay(println(s"Pushing $n to Queue")))
.map { n =>
val entryTime = currentTimeNow
(n.toDouble, "Service", entryTime)
// timer.sleep(Random.between(10, 30).seconds) I have tried adding it here but the same result
}
.through(q1.enqueue)
}
def getFromQueue: Stream[IO, Unit] = {
timer.sleep(Random.between(10, 30).seconds)
q1.dequeue
.map { n =>
val exitTime = currentTimeNow
(n._1, "Service", n._3, exitTime)
}
.evalMap(n => IO.delay(println(s"Pulling from queue $n")))
}
}
object Five2 extends IOApp {
override def run(args: List[String]): IO[ExitCode] = {
val program = for {
q <- Queue.bounded[IO, (Double, String, String)](10)
b = new Tst(q)
_ <- b.storeInQueue.compile.drain.start
_ <- b.getFromQueue.compile.drain
} yield ()
program.as(ExitCode.Success)
}
}
得到gitter的帮助:以下是答案:
你在那里做事的方式有几个问题。首先,你的timer.sleep呼叫被忽略。这是因为它返回一个IO,除非对其进行求值,否则IO不会执行任何操作。因此,您希望在流的管道中执行它,您可以使用类似
q1.dequeue.evalTap(_ => timer.sleep(Random.between(10, 30).seconds))).map { n => … other things … }
第二件事是,我不知道currentTimeNow函数是如何工作的,但通常在函数堆栈中,获取当前时间是一个有效的操作,因此使用计时器可以获得如下的当前时间:
Stream(1, 2, 3)
.covary[IO]
.evalTap(n => IO.delay(println(s"Pushing $n to Queue")))
.evalMap { n =>
timer.clock.realTime(java.util.concurrent.TimeUnit.MILLISECONDS)
.map(entryTime => (n.toDouble, “Service”, entryTime))
}
.through(q1.enqueue)
不,不是,我已经编辑了这个问题,并且指定了currentTimeNow方法的实现。
Stream(1, 2, 3)
.covary[IO]
.evalTap(n => IO.delay(println(s"Pushing $n to Queue")))
.evalMap { n =>
timer.clock.realTime(java.util.concurrent.TimeUnit.MILLISECONDS)
.map(entryTime => (n.toDouble, “Service”, entryTime))
}
.through(q1.enqueue)