-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
One module, blocking & non-blocking operations, misc. #385
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
As discussed in issue #247.
Improve wording. Co-authored-by: Maxim Schuwalow <16665913+mschuwalow@users.noreply.github.com>
…ar/next-gen # Conflicts: # nio-core/src/main/scala/zio/nio/core/package.scala # nio-core/src/test/scala/zio/nio/core/channels/ChannelSpec.scala
The channel APIs (except for asyncrhonous channels) are now split into three parts: * Blocking (BlockingOps) * Non-blocking (NonBlockingOps) * Core (On the channel itself) Blocking and non-blocking APIs are the same in many cases (GatheringByteOps and ScatteringByteOps), but there are some differences. The blocking API usage is performed as a block in by using the `useBlocking` method on the channel. This method switches to the ZIO blocking thread pool and installs interrupt handling, which is necessary to interrupt blocking I/O calls if the ZIO fiber is interrupted. This imposes an overhead ever time it is needed, this approach aims to pay the cost once per channel, rather than once per read or write. Non-blocking usage does not require the special setup required for blocking, but for consistency the API is accessed the same way, via the `useNonBlocking` method on the channel.
* Use new ZStream adaptors for Java iterators and streams. * Use the ZIO-NIO Charset wrapper * Implement `lines` method * Implement `copy` method
Use meaningful names for the InetSocketAddress constructors. Make binding to an automatically assigned socket address explicit.
(cherry picked from commit a5c3517)
(cherry picked from commit cd43375)
Co-authored-by: Jakub Czuchnowski <jakub.czuchnowski@gmail.com> (cherry picked from commit 73c605a)
* Update sbt-scala-native-crossproject, ... to 1.1.0 * Update sbt-scala-native-crossproject, ... to 1.1.0
|
quelgar
reviewed
Aug 15, 2021
mijicd
previously approved these changes
Sep 1, 2021
quelgar
previously approved these changes
Sep 4, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Credit for this PR belongs to @quelgar, with merely some compilation and merge fixes by me
To do:
ManagedBlockingNioOps
andManagedNonBlockingNioOps
zio-nio
SelectionKey
Description of changes:
Addtions to ZIO-NIO
These are the changes and additions this branch has added to ZIO-NIO version 1.0.0-RC10 (the latest at this writing). The changes are:
WatchService
API including streamingRicher API forAlready in RC11InetSocketAddress
Selector#select
can be interruptedOnly One Module
The two modules — core and "high-level" — have been combined into a single module.
All resource acquisition is now done within
ZManaged
, with channel close being public to allow early release if desired. This removed the only significant difference between the core and high-level modules. A single module avoids duplication and makes the API simpler.ZManaged
supports resources being used beyond a single lexical scope, which is sometimes needed when using NIO. The resource management docs explain the details.Separate APIs for Non-Blocking and Interruptible Blocking
NIO has a number of methods that can be used in either blocking or non-blocking mode. A problem with this is they often have different behaviors in depending on the mode. For example, the
ServerSocketChannel#accept
method can return null, but only if the channel is non-blocking mode. It is desirable for the types to reflect this modal characteristic.A larger issue is that of blocking channel operations, which are surprisingly tricky to make work well for an asynchronous effect system like ZIO. For blocking operations we want to:
blocking
threadpoolBecause RC10 ZIO-NIO does not currently setup interrupt handling, it isn't possible to interrupt fibers that are performing blocking I/O. This leads to problems such as programs not exiting when they receive a SIGTERM (control-C).
Simply performing these two steps on every blocking read or write leads to poor performance, as both steps impose some overhead. The blocking pool overhead can be solved by running the entire NIO section of your program on the blocking pool (if you know you're using blocking operations). However, the interruption setup can't be done at such a high level, as it specific to each channel instance.
My solution to all the above factors is to offer bracketed access to custom blocking and non-blocking APIs. This allows a set of blocking operations to be performed safely while only paying the blocking setup cost once per bracket. This bracketed API is present on all channels that can operate in blocking mode.
For example, to perform a set of blocking operations on a channel:
useBlocking
will put the channel into blocking mode, and perform the two setup steps described above: use theblocking
pool and setup interruption handling. Theops
argument provided to you offers all the blocking operations supported by the channel, including stream-based ones.useNonBlocking
will put the channel into non-blocking mode, and provide an operations argument with an API specific to non-blocking use.Asynchronous Channel Improvements
With current ZIO-NIO, fibers blocked waiting for a callback from an asynchronous channel cannot be interrupted. This leads to problems such as programs not exiting when they receive a SIGTERM (control-C). This branch fixes that.
Some NIO methods that were overlooked are also added.
Streaming Read and Write
ZStream
-based reading andZSink
-based writing are now built in for all channel types.For asynchronous channels, the methods are built into channel:
For blocking channels, the stream or sink should be used within
useBlocking
:While the stream and sink can be used with non-blocking channels, this probably isn't a good idea. Non-blocking channels will busy-wait on reads and writes until the channel is actually ready. This is worse than blocking the thread. Non-blocking channels really need to be used with a
Selector
to be useful.Streaming WatchService API
See the example.