Resourceful Streams
In the Stream module, you’ll find that most of the constructors offer a special variant designed for lifting a scoped resource into a Stream
. When you use these specific constructors, you’re essentially creating streams that are inherently safe with regards to resource management. These constructors, before creating the stream, handle the resource acquisition, and after the stream’s usage, they ensure its proper closure.
Stream also provides us with Stream.acquireRelease
and Stream.finalizer
constructors that share similarities with Effect.acquireRelease
and Effect.addFinalizer
. These tools empower us to perform cleanup or finalization tasks before the stream concludes its operation.
In this section, we’ll explore an example that demonstrates the use of Stream.acquireRelease
when working with file operations.
In this code snippet, we’re simulating file operations using the open
function. The Stream.acquireRelease
function is employed to ensure that the file is correctly opened and closed, and we then process the lines of the file using the acquired resource.
In this section, we’ll explore the concept of finalization in streams. Finalization allows us to execute a specific action before a stream ends. This can be particularly useful when we want to perform cleanup tasks or add final touches to a stream.
Imagine a scenario where our streaming application needs to clean up a temporary directory when it completes its execution. We can achieve this using the Stream.finalizer
function:
In this code example, we start with our application logic represented by the application
stream. We then use Stream.finalizer
to define a finalization step, which deletes a temporary directory and logs a message. This ensures that the temporary directory is cleaned up properly when the application completes its execution.
In this section, we’ll explore a scenario where we need to perform actions after the finalization of a stream. To achieve this, we can utilize the Stream.ensuring
operator.
Consider a situation where our application has completed its primary logic and finalized some resources, but we also need to perform additional actions afterward. We can use Stream.ensuring
for this purpose:
In this code example, we start with our application logic represented by the Application Logic.
message. We then use Stream.finalizer
to specify the finalization step, which logs Finalizing the stream
. After that, we use Stream.ensuring
to indicate that we want to perform additional tasks after the stream’s finalization, resulting in the message Performing additional tasks after stream's finalization
. This ensures that our post-finalization actions are executed as expected.