Skip to content

Commit c53e153

Browse files
committed
Readme
1 parent afd9b52 commit c53e153

File tree

1 file changed

+20
-25
lines changed

1 file changed

+20
-25
lines changed

README.md

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
[![javadoc](https://javadoc.io/badge2/com.softwaremill.jox/channels/javadoc.svg)](https://javadoc.io/doc/com.softwaremill.jox/channels)
77

88
Modern concurrency for Java 21 (backed by virtual threads, see [Project Loom](https://openjdk.org/projects/loom/)).
9-
Requires JDK 21.
109
Includes:
1110

1211
* Fast and Scalable Channels in Java. Inspired by the "Fast and Scalable Channels in Kotlin Coroutines"
1312
[paper](https://arxiv.org/abs/2211.04986), and
1413
the [Kotlin implementation](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/common/src/channels/BufferedChannel.kt).
1514
* Programmer-friendly structured concurrency
16-
* Blocking, synchronous, functional streaming operators
15+
* Blocking, synchronous, functional streaming
1716

1817
JavaDocs can be browsed
1918
at [https://javadoc.io](https://www.javadoc.io/doc/com.softwaremill.jox/core/latest/com.softwaremill.jox/com/softwaremill/jox/package-summary.html).
@@ -35,7 +34,6 @@ For a Scala version, see the [Ox project](https://github.com/softwaremill/ox).
3534

3635
* [Channels](#channels)
3736
* [Structured concurrency](#structured-concurrency)
38-
* [Streaming](#streaming)
3937
* [Flows](#lazy-streaming---flows)
4038

4139
## Channels
@@ -343,6 +341,8 @@ ChainedKotlinBenchmark.channelChain_defaultDispatcher 16
343341

344342
## Structured concurrency
345343

344+
Requires the current LTS release of Java - JDK 21 (won't work with newer versions).
345+
346346
### Dependency
347347

348348
Maven:
@@ -431,17 +431,14 @@ so that it can be properly handled. Moreover, no detail is lost: all exceptions
431431
suppressed exceptions.
432432

433433
As `JoxScopeExecutionException` is unchecked, we introduced utility method called
434-
`JoxScopeExecutionException#unwrapAndThrow`.
435-
If the wrapped exception is instance of any of passed classes, this method unwraps original exception and throws it as
436-
checked exception, `throws` signature forces exception handling.
437-
If the wrapped exception is not instance of any of passed classes, **nothing happens**.
438-
All suppressed exceptions are rewritten from `JoxScopeExecutionException`
434+
`JoxScopeExecutionException#unwrapAndThrow`. If the wrapped exception is an instance of any of the passed classes, this
435+
method unwraps original exception and throws it as checked exception; then the `throws` signature forces exception
436+
handling. If the wrapped exception is not instance of any of the passed classes, **nothing happens**. All suppressed
437+
exceptions from `JoxScopeExecutionException` are added as suppressed to the unwrapped one.
439438

440439
**Note** `throws` signature points to the closest super class of passed arguments.
441440
Method does **not** rethrow `JoxScopeExecutionException` by default.
442-
So it is advised to manually rethrow it after calling `unwrapAndThrow` method.
443-
444-
e.g.
441+
So it is advised to manually rethrow it after calling `unwrapAndThrow` method, e.g.:
445442

446443
```java
447444
import com.softwaremill.jox.structured.JoxScopeExecutionException;
@@ -651,10 +648,10 @@ The `FlowEmit` instance is used to emit elements by the flow, that is process th
651648
pipeline. This method only completes once the element is fully processed, and it might throw exceptions in case there's
652649
a processing error.
653650

654-
As part of the callback, you can create `Scope`, fork background computations or run other flows asynchronously.
651+
As part of the callback, you can create a `Scope`, fork background computations or run other flows asynchronously.
655652
However, take care **not** to share the `FlowEmit` instance across threads. That is, instances of `FlowEmit` are
656-
thread-unsafe and should only be used on the calling thread.
657-
The lifetime of `FlowEmit` should not extend over the duration of the invocation of `usingEmit`.
653+
thread-unsafe and should only be used on the calling thread. The lifetime of `FlowEmit` should not extend over the
654+
duration of the invocation of `usingEmit`.
658655

659656
Any asynchronous communication should be best done with `Channel`s. You can then manually forward any elements received
660657
from a channel to `emit`, or use e.g. `FlowEmit.channelToEmit`.
@@ -727,18 +724,17 @@ Processes the elements one-by-one on the thread that is invoking the run method.
727724
### Transforming flows: concurrency
728725

729726
A number of flow transformations introduces asynchronous boundaries. For example,
730-
`.mapPar(int parallelism, Function<T,U> mappingFunction)` describes a flow,
731-
which runs the pipeline defined so far in the background, emitting elements to a `channel`. Another `fork` reads these
732-
elements and runs up to `parallelism` invocations of `mappingFunction` concurrently. Mapped elements are then emitted by
733-
the returned flow.
727+
`.mapPar(int parallelism, Function<T,U> mappingFunction)` describes a flow, which runs the pipeline defined so far in
728+
the background, emitting elements to a `channel`. Another `fork` reads these elements and runs up to `parallelism`
729+
invocations of `mappingFunction` concurrently. Mapped elements are then emitted by the returned flow.
734730

735731
Behind the scenes, a new concurrency `Scope` is created along with a number of forks. In case of any exceptions,
736732
everything is cleaned up before the flow propagates the exceptions. The `.mapPar` logic ensures that any exceptions from
737733
the preceding pipeline are propagated through the channel.
738734

739735
Some other stages which introduce concurrency include `.merge`, `.interleave`, `.groupedWithin` and `I/O` stages. The
740736
created channels serve as buffers between the pipeline stages, and their capacity is defined by the `ScopedValue`
741-
`Channel.BUFFER_SIZE` in the scope, or default `Channel.DEFAULT_BUFFER_SIZE` is used.
737+
`Flow.CHANNEL_BUFFER_SIZE` in the scope, or default `Channel.DEFAULT_BUFFER_SIZE` is used.
742738

743739
Explicit asynchronous boundaries can be inserted using `.buffer()`. This might be useful if producing the next element
744740
to emit, and consuming the previous should run concurrently; or if the processing times of the consumer varies, and the
@@ -776,11 +772,10 @@ the pipeline described by the flow, and emits its elements onto the returned cha
776772
### Text transformations and I/O operations
777773

778774
For smooth operations on `byte[]`, we've created a wrapper class `ByteChunk`. And for smooth type handling we created a
779-
dedicated `ByteFlow`, a subtype of `Flow<ByteChunk>`.
780-
To be able to utilize text and I/O operations, you need to create or transform into `ByteFlow`. It can be created via
781-
`Flows.fromByteArray` or `Flows.fromByteChunk`.
782-
`Flow` containing `byte[]` or `ByteChunk` can be transformed by using `toByteFlow()` method. Any other flow can be
783-
transformed by using `toByteFlow()` with mapping function.
775+
dedicated `ByteFlow`, a subtype of `Flow<ByteChunk>`. To be able to utilize text and I/O operations, you need to create
776+
or transform into `ByteFlow`. It can be created via `Flows.fromByteArray` or `Flows.fromByteChunk`. `Flow` containing
777+
`byte[]` or `ByteChunk` can be transformed by using `toByteFlow()` method. Any other flow can be transformed by using
778+
`toByteFlow()` with mapping function.
784779

785780
#### Text operations
786781

@@ -858,4 +853,4 @@ We offer commercial development services. [Contact us](https://softwaremill.com)
858853

859854
## Copyright
860855

861-
Copyright (C) 2023-2024 SoftwareMill [https://softwaremill.com](https://softwaremill.com).
856+
Copyright (C) 2023-2025 SoftwareMill [https://softwaremill.com](https://softwaremill.com).

0 commit comments

Comments
 (0)