Replies: 2 comments 2 replies
-
Have you looked at ZChannel? It is exactly |
Beta Was this translation helpful? Give feedback.
-
Yes, there are actually several data types like this in ZIO. One is Another is There is no guarantee that a channel will emit an output for each input, and in fact some channels may emit multiple outputs with no input or consume multiple inputs with no output, but you can create channels that emit an output for each input. You can create channels with a variety of channel constructors . For example, you can use |
Beta Was this translation helpful? Give feedback.
-
When trying to implement a task combinator that repeatedly executes the task and reports the execution status to the provided
ZSink
(#7195), it occured to me that the cleanest way to achieve this would involve the coroutime abstraction. Sadly, this abstraction apparently doesn't exist in ZIO. Here I'm trying to explore what it could look like.I may be wrong, but I see a coroutine as a computation that, when executed, (1) can produce one or more intermediate outputs and (2) eventually finishes with a result. Intermediate outputs are given to the caller of the coroutine, which processes them and then returns control to the coroutine (or not). While the caller processes an intermediate output, the coroutine's execution is suspended, and is resumed when the caller says so. As an optional feature, we can also envision the possibility to pass intermediate input from the caller back to the coroutine when the latter is resumed by the former.
So, we could have the type
ZCoroutine[R, E, +TOutput, -TResume, +TResult]
, which describes a coroutine that runs in theR
environment, can fail with a errorE
, emits intermediate output values of typeTOutput
, accepts back intermediate input values of typeTResume
, and finally produces the end result of typeTResult
.From the outside, a coroutine looks similar to
ZStream
, except that a stream doesn't produce the end result and doesn't have the possibility to receive intermediate input values. However, the internal structure of coroutine would be different: it would be a computation like aZIO
, with the ability to yield back to the caller at any point inside the computation (from a deeply nested sub-computation within loops, conditionals, internal functions and so on).A coroutine can be (naively) modelled like this:
So it's just a function that receives a "yield function" of type
TParam => ZIO[R, E, TResult]
and produces a computation.For example:
Now, we need a way to run a coroutine.
ZStream
has aZSink
that complements it; similarly, we might want a complimentary abstraction for a coroutine, something that accepts coroutine's intermediate inputs, provides intermediate outputs in return, has an optional itnernal state that could be influenced by intermediate outputs and influences intermediate inputs, and produces the final result from the coroutine's final result and the accumulated internal state. I don't readily have a name for this abstraction, it could be, for example,ZCoprocessor[R, E, -TOutput, +TResume, TCoResult, +TResult]
:ZCoprocessor
would be created using factory functions and various transformations, much likeZSink
is.With this in mind, we could have the "run" function:
This function would create a co-processor instance, instantiate the coroutine computation, handle its intermediate outputs (feeding them sequentially to the co-processor instance, even if the coroutine tries to call
yieldFunction
concurrently), wait for completion of coroutine computation, deactivate theyieldFunction
after completion (so that, if possible forked computations within the coroutine call theyieldFunction
, it would fail), and map the end result via the co-processor instance.This model doesn't include the possibility to not returning control to the co-routine after it produces an itnermediate output; this possibility could be implemented by using a special
Shutdown
error that the co-procesor'syieldFunction
is allowed to return:(Not sure how it would actually interact with the coroutine computation: return the
Shutdown
error to it fromyieldFunction
? Interrupt it? This needs more thought.)Now, all of this is more like a dream rather than an actual proposal. It's probably quite difficult to even write a good API for this, let alone implement it. I may be able to create a rudimentary, non-production-ready implementation for my own use, though. :) And if anyone would actually create a proper implementation, it could be a noteworthy addition to the library.
Beta Was this translation helpful? Give feedback.
All reactions