scala.js 是否与 scala ZIO 一起使用?我想在 scala.js 中使用 scala ZIO 我只知道如何在普通应用程序中使用 scala ZIO 有谁知道如何在 scala.js 中使用它?
我对Scala和ZIO有点陌生,遇到了一个奇怪的难题。
我想设置一个包含ZIO队列的ZIO环境,以后offer再take从此共享队列中使用不同的ZIO任务。
我试图这样定义我的环境
trait MainEnv extends Console with Clock
{
val mainQueue = Queue.unbounded[String]
}
Run Code Online (Sandbox Code Playgroud)
并从这样的单独任务访问队列
for {
env <- ZIO.environment[MainEnv]
queue <- env.mainQueue
...
Run Code Online (Sandbox Code Playgroud)
但是在测试中,我观察到每个单独的任务都有一个单独的Queue实例。
寻找签名unbounded
def unbounded[A]: UIO[Queue[A]]
Run Code Online (Sandbox Code Playgroud)
我观察到它并不会立即返回一个队列,而是返回一个返回队列的效果,因此虽然观察到的行为是有道理的,但这根本不是我所希望的,并且我没有看到一种清晰的方式来获得行为我想要。
我们将不胜感激关于如何实现我的目标的任何建议,这些目标是通过环境中存储的共享队列来设置不同的任务进行通信。
供参考的是我的代码和输出。
bash-3.2$ sbt run
[info] Loading project definition from /private/tmp/env-q/project
[info] Loading settings for project root from build.sbt ...
[info] Set current project to example (in build file:/private/tmp/env-q/)
[info] Compiling 1 Scala source to /private/tmp/env-q/target/scala-2.12/classes ...
[info] Done compiling.
[info] Packaging /private/tmp/env-q/target/scala-2.12/example_2.12-0.0.1-SNAPSHOT.jar …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个 ZIO 模块的示例,它有两个实现:
我的通用界面如下所示:
trait Service[R] {
def load[T <: Component](ref: CompRef): RIO[R, T]
}
Run Code Online (Sandbox Code Playgroud)
现在我的 YAML 实现看起来像:
def loadYaml[T <: Component: Decoder](ref: CompRef): RIO[Any, T] = {...}
Run Code Online (Sandbox Code Playgroud)
这Decoder是特定于实现的。
现在的问题是如何从 Service 实现委托给loadYaml.
我尝试了以下方法:
val components: Components.Service[Any] = new Components.Service[Any] {
implicit val decodeComponent: Decoder[Component] =
List[Decoder[Component]](
Decoder[DbConnection].widen,
...
).reduceLeft(_ or _)
def load[T <: Component](ref: CompRef): RIO[Any, T] = loadYaml[T] (ref)
}
Run Code Online (Sandbox Code Playgroud)
这给了我:
Error:(62, 20) could …Run Code Online (Sandbox Code Playgroud) 我想按顺序运行两个集成测试。如何在ZIO Test 中实现这一点?
这是套房:
suite("Undeploy a Package")(
testM("There is a Package") {
PackageDeployer.deploy(pckg) *> // first deploy
assertM(PackageUndeployer.undeploy(pckg), equalTo(StatusCode.NoContent))
},
testM(s"There is no Package") {
assertM(PackageUndeployer.undeploy(pckg), equalTo(StatusCode.NotFound))
})
Run Code Online (Sandbox Code Playgroud)
ZIO Test并行运行这两个测试。有没有办法强制它们按顺序运行?
我正在使用 ZIO: https: //github.com/zio/zio
在我的build.sbt:
"dev.zio" %% "zio" % "1.0.0-RC9"
Run Code Online (Sandbox Code Playgroud)
无论我尝试什么,每次需要时都会计算我的结果:
val t = Task {
println(s"Compute")
12
}
val r = unsafeRun(for {
tt1 <- t
tt2 <- t
} yield {
tt1 + tt2
})
println(r)
Run Code Online (Sandbox Code Playgroud)
对于此示例,日志如下所示:
Compute
Compute
24
Run Code Online (Sandbox Code Playgroud)
我尝试过Promise:
val p = for {
p <- Promise.make[Nothing, Int]
_ <- p.succeed {
println(s"Compute - P")
48
}
r <- p.await
} yield {
r
}
val r = unsafeRun(for {
tt1 <- …Run Code Online (Sandbox Code Playgroud) 我开始尝试 ZIO,并尝试运行以下高度复杂的程序:
import logger.{Logger, _}
import zio.console._
import zio.{system, _}
object MyApp extends App {
override def run(args: List[String]): ZIO[ZEnv, Nothing, Int] = {
app
.provideSome[Logger](_ => Slf4jLogger.create) //1
.fold(_ => 1, _ => 0)
}
val app: ZIO[Console with system.System with Logger, SecurityException, Unit] =
for {
_ <- info("This message from the logger") //2
maybeUser <- system.env("USER")
_ <- maybeUser match {
case Some(userName) => putStrLn(s"Hello ${userName}!")
case None => putStrLn("I don't know your name")
}
} yield …Run Code Online (Sandbox Code Playgroud) 我知道 ZIO 维护自己的堆栈,即zio.internal.FiberContext#stack,它保护递归函数,如
def getNameFromUser(askForName: UIO[String]): UIO[String] =
for {
resp <- askForName
name <- if (resp.isEmpty) getNameFromUser(askForName) else ZIO.succeed(resp)
} yield name
Run Code Online (Sandbox Code Playgroud)
从堆栈溢出。然而,它们仍然消耗 ZIO 解释器堆栈中的空间,这可能导致OutOfMemoryError非常深的递归。你将如何重写getNameFromUser上面的函数,即使askForName效果在很长一段时间内返回空字符串也不会炸毁堆?
我创建了两个版本的服务。第一个使用Futures,另一个使用ZIO效果。
我有一个简单的方法,使用Future结果效果:
def get(id: String)(implicit executionContext: ExecutionContext): Future[Data]
Run Code Online (Sandbox Code Playgroud)
我还有一些其他版本使用ZIO[SomeEnv, SomeError, Data]:
def get(id: String): ZIO[SomeEnv, SomeError, Data]
Run Code Online (Sandbox Code Playgroud)
现在,我需要创建某种适配器,它将从一个版本或另一个版本返回数据:
def returnDataFromServiceVersion(version: Int) : ??? = {
if(version == 1) futureService.get(...)
else zioService.get(...)
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是返回类型。我不知道如何转换ZIO为未来或Future转换ZIO为具有共同的返回类型。我尝试使用ZIO.fromFuture{...}ortoFuture()但没有帮助。我的问题是 - 如何创建此returnDataFromServiceVersion方法以将其与这两种服务一起使用?我需要在这里有共同的返回类型。
或者也许有另一种方法可以解决这个问题?
zio-streams 提供throttleShape了
/**
* Delays the chunks of this stream according to the given bandwidth parameters using the token bucket
* algorithm. Allows for burst in the processing of elements by allowing the token bucket to accumulate
* tokens up to a `units + burst` threshold. The weight of each chunk is determined by the `costFn`
* function.
*/
final def throttleShape(units: Long, duration: Duration, burst: Long = 0)(
costFn: Chunk[O] => Long
): ZStream[R with Clock, E, …Run Code Online (Sandbox Code Playgroud) 我试过
assert(anOption)(contains("x"))
Run Code Online (Sandbox Code Playgroud)
但这仅适用于 Iterables,例如 List 或 Seq。
scala ×10
zio ×10
zio-test ×2
circe ×1
future ×1
implicit ×1
scala-cats ×1
scala.js ×1
throttling ×1
typeclass ×1