Skip to content

Commit 2fdcd3d

Browse files
authored
unify code formatting (#92)
1 parent 8fe4f83 commit 2fdcd3d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1740
-575
lines changed

.editorconfig

Lines changed: 1232 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ class Demo2 {
120120
}
121121
```
122122

123-
There is also a possibility to pass `Channel`'s buffer size via `ScopedValue`.
124-
The channel must be created via `Channel.withScopedBufferSize()` to get the value.
123+
There is also a possibility to pass `Channel`'s buffer size via `ScopedValue`.
124+
The channel must be created via `Channel.withScopedBufferSize()` to get the value.
125125

126126
If no value is in the scope, the default buffer size `Channel.DEFAULT_BUFFER_SIZE` is used
127127

@@ -432,8 +432,10 @@ Jox implements the "let it crash" model. When an error occurs, the entire scope
432432
so that it can be properly handled. Moreover, no detail is lost: all exceptions are preserved, either as causes, or
433433
suppressed exceptions.
434434

435-
As `JoxScopeExecutionException` is unchecked, we introduced utility method called `JoxScopeExecutionException#unwrapAndThrow`.
436-
If the wrapped exception is instance of any of passed classes, this method unwraps original exception and throws it as checked exception, `throws` signature forces exception handling.
435+
As `JoxScopeExecutionException` is unchecked, we introduced utility method called
436+
`JoxScopeExecutionException#unwrapAndThrow`.
437+
If the wrapped exception is instance of any of passed classes, this method unwraps original exception and throws it as
438+
checked exception, `throws` signature forces exception handling.
437439
If the wrapped exception is not instance of any of passed classes, **nothing happens**.
438440
All suppressed exceptions are rewritten from `JoxScopeExecutionException`
439441

@@ -442,6 +444,7 @@ Method does **not** rethrow `JoxScopeExecutionException` by default.
442444
So it is advised to manually rethrow it after calling `unwrapAndThrow` method.
443445

444446
e.g.
447+
445448
```java
446449
import com.softwaremill.jox.structured.JoxScopeExecutionException;
447450
import com.softwaremill.jox.structured.Scopes;
@@ -651,27 +654,31 @@ implementation 'com.softwaremill.jox:flows:tbd'
651654

652655
A `Flow<T>` describes an asynchronous data transformation pipeline. When run, it emits elements of type `T`.
653656

654-
Flows are lazy, evaluation (and any effects) happen only when the flow is run. Flows might be finite or infinite; in the latter case running a flow never ends normally; it might be interrupted, though. Finally, any exceptions that occur when evaluating the flow's logic will be thrown when running the flow, after any cleanup logic completes.
657+
Flows are lazy, evaluation (and any effects) happen only when the flow is run. Flows might be finite or infinite; in the
658+
latter case running a flow never ends normally; it might be interrupted, though. Finally, any exceptions that occur when
659+
evaluating the flow's logic will be thrown when running the flow, after any cleanup logic completes.
655660

656661
### Creating Flows
657662

658663
There are number of methods in the `Flows` class which allows to create a `Flow`.
659664

660665
```java
661666
import java.time.Duration;
667+
662668
import com.softwaremill.jox.flows.Flows;
663669

664670
public class Demo {
665671

666-
public static void main(String[] args) {
667-
Flows.fromValues(1, 2, 3); // a finite flow
668-
Flows.tick(Duration.ofSeconds(1), "x"); // an infinite flow emitting "x" every second
669-
Flows.iterate(0, i -> i + 1); // an infinite flow iterating from 0
670-
}
672+
public static void main(String[] args) {
673+
Flows.fromValues(1, 2, 3); // a finite flow
674+
Flows.tick(Duration.ofSeconds(1), "x"); // an infinite flow emitting "x" every second
675+
Flows.iterate(0, i -> i + 1); // an infinite flow iterating from 0
676+
}
671677
}
672678
```
673-
Note that creating a flow as above doesn't emit any elements, or execute any of the flow's logic. Only when run, the elements are emitted and any effects that are part of the flow's stages happen.
674679

680+
Note that creating a flow as above doesn't emit any elements, or execute any of the flow's logic. Only when run, the
681+
elements are emitted and any effects that are part of the flow's stages happen.
675682

676683
Flows can also be created using `Channel` `Source`s:
677684

@@ -721,19 +728,27 @@ public class Demo {
721728
}
722729
```
723730

724-
The `FlowEmit` instance is used to emit elements by the flow, that is process them further, as defined by the downstream pipeline. This method only completes once the element is fully processed, and it might throw exceptions in case there's a processing error.
731+
The `FlowEmit` instance is used to emit elements by the flow, that is process them further, as defined by the downstream
732+
pipeline. This method only completes once the element is fully processed, and it might throw exceptions in case there's
733+
a processing error.
725734

726-
As part of the callback, you can create `Scope`, fork background computations or run other flows asynchronously. However, take care **not** to share the `FlowEmit` instance across threads. That is, instances of `FlowEmit` are thread-unsafe and should only be used on the calling thread.
735+
As part of the callback, you can create `Scope`, fork background computations or run other flows asynchronously.
736+
However, take care **not** to share the `FlowEmit` instance across threads. That is, instances of `FlowEmit` are
737+
thread-unsafe and should only be used on the calling thread.
727738
The lifetime of `FlowEmit` should not extend over the duration of the invocation of `usingEmit`.
728739

729-
Any asynchronous communication should be best done with `Channel`s. You can then manually forward any elements received from a channel to `emit`, or use e.g. `FlowEmit.channelToEmit`.
740+
Any asynchronous communication should be best done with `Channel`s. You can then manually forward any elements received
741+
from a channel to `emit`, or use e.g. `FlowEmit.channelToEmit`.
730742

731743
### Transforming flows: basics
732744

733-
Multiple transformation stages can be added to a flow, each time returning a new `Flow` instance, describing the extended pipeline. As before, no elements are emitted or transformed until the flow is run, as flows are lazy. There's a number of pre-defined transformation stages:
745+
Multiple transformation stages can be added to a flow, each time returning a new `Flow` instance, describing the
746+
extended pipeline. As before, no elements are emitted or transformed until the flow is run, as flows are lazy. There's a
747+
number of pre-defined transformation stages:
734748

735749
```java
736750
import java.util.Map;
751+
737752
import com.softwaremill.jox.flows.Flows;
738753

739754
public class Demo {
@@ -749,7 +764,8 @@ public class Demo {
749764
}
750765
```
751766

752-
You can also define arbitrary element-emitting logic, using each incoming element using `.mapUsingEmit`, similarly to `Flows.usingEmit` above.
767+
You can also define arbitrary element-emitting logic, using each incoming element using `.mapUsingEmit`, similarly to
768+
`Flows.usingEmit` above.
753769

754770
### Running flows
755771

@@ -762,15 +778,16 @@ import com.softwaremill.jox.flows.Flows;
762778

763779
public class Demo {
764780

765-
public static void main(String[] args) throws Exception {
766-
Flows.fromValues(1, 2, 3).runToList(); // List(1, 2, 3)
767-
Flows.fromValues(1, 2, 3).runForeach(System.out::println);
768-
Flows.tick(Duration.ofSeconds(1), "x").runDrain(); // never finishes
769-
}
781+
public static void main(String[] args) throws Exception {
782+
Flows.fromValues(1, 2, 3).runToList(); // List(1, 2, 3)
783+
Flows.fromValues(1, 2, 3).runForeach(System.out::println);
784+
Flows.tick(Duration.ofSeconds(1), "x").runDrain(); // never finishes
785+
}
770786
}
771787
```
772788

773-
Running a flow is a blocking operation. Unless asynchronous boundaries are present (explicit or implicit, more on this below), the entire processing happens on the calling thread. For example such a pipeline:
789+
Running a flow is a blocking operation. Unless asynchronous boundaries are present (explicit or implicit, more on this
790+
below), the entire processing happens on the calling thread. For example such a pipeline:
774791

775792
```java
776793
import com.softwaremill.jox.flows.Flows;
@@ -785,19 +802,28 @@ public class Demo {
785802
}
786803
}
787804
```
788-
Processes the elements one-by-one on the thread that is invoking the run method.
789805

806+
Processes the elements one-by-one on the thread that is invoking the run method.
790807

791808
### Transforming flows: concurrency
792809

793-
A number of flow transformations introduces asynchronous boundaries. For example, `.mapPar(int parallelism, Function<T,U> mappingFunction)` describes a flow,
794-
which runs the pipeline defined so far in the background, emitting elements to a `channel`. Another `fork` reads these elements and runs up to `parallelism` invocations of `mappingFunction` concurrently. Mapped elements are then emitted by the returned flow.
810+
A number of flow transformations introduces asynchronous boundaries. For example,
811+
`.mapPar(int parallelism, Function<T,U> mappingFunction)` describes a flow,
812+
which runs the pipeline defined so far in the background, emitting elements to a `channel`. Another `fork` reads these
813+
elements and runs up to `parallelism` invocations of `mappingFunction` concurrently. Mapped elements are then emitted by
814+
the returned flow.
795815

796-
Behind the scenes, a new concurrency `Scope` is created along with a number of forks. In case of any exceptions, everything is cleaned up before the flow propagates the exceptions. The `.mapPar` logic ensures that any exceptions from the preceding pipeline are propagated through the channel.
816+
Behind the scenes, a new concurrency `Scope` is created along with a number of forks. In case of any exceptions,
817+
everything is cleaned up before the flow propagates the exceptions. The `.mapPar` logic ensures that any exceptions from
818+
the preceding pipeline are propagated through the channel.
797819

798-
Some other stages which introduce concurrency include `.merge`, `.interleave`, `.groupedWithin` and `I/O` stages. The created channels serve as buffers between the pipeline stages, and their capacity is defined by the `ScopedValue` `Channel.BUFFER_SIZE` in the scope, or default `Channel.DEFAULT_BUFFER_SIZE` is used.
820+
Some other stages which introduce concurrency include `.merge`, `.interleave`, `.groupedWithin` and `I/O` stages. The
821+
created channels serve as buffers between the pipeline stages, and their capacity is defined by the `ScopedValue`
822+
`Channel.BUFFER_SIZE` in the scope, or default `Channel.DEFAULT_BUFFER_SIZE` is used.
799823

800-
Explicit asynchronous boundaries can be inserted using `.buffer()`. This might be useful if producing the next element to emit, and consuming the previous should run concurrently; or if the processing times of the consumer varies, and the producer should buffer up elements.
824+
Explicit asynchronous boundaries can be inserted using `.buffer()`. This might be useful if producing the next element
825+
to emit, and consuming the previous should run concurrently; or if the processing times of the consumer varies, and the
826+
producer should buffer up elements.
801827

802828
### Interoperability with channels
803829

@@ -825,20 +851,28 @@ public class Demo {
825851
}
826852
```
827853

828-
The method above needs to be run within a concurrency scope, as `.runToChannel()` creates a background fork which runs the pipeline described by the flow, and emits its elements onto the returned channel.
854+
The method above needs to be run within a concurrency scope, as `.runToChannel()` creates a background fork which runs
855+
the pipeline described by the flow, and emits its elements onto the returned channel.
829856

830857
### Text transformations and I/O operations
831858

832-
For smooth operations on `byte[]`, we've created a wrapper class `ByteChunk`. And for smooth type handling we created a dedicated `ByteFlow`, a subtype of `Flow<ByteChunk>`.
833-
To be able to utilize text and I/O operations, you need to create or transform into `ByteFlow`. It can be created via `Flows.fromByteArray` or `Flows.fromByteChunk`.
834-
`Flow` containing `byte[]` or `ByteChunk` can be transformed by using `toByteFlow()` method. Any other flow can be transformed by using `toByteFlow()` with mapping function.
859+
For smooth operations on `byte[]`, we've created a wrapper class `ByteChunk`. And for smooth type handling we created a
860+
dedicated `ByteFlow`, a subtype of `Flow<ByteChunk>`.
861+
To be able to utilize text and I/O operations, you need to create or transform into `ByteFlow`. It can be created via
862+
`Flows.fromByteArray` or `Flows.fromByteChunk`.
863+
`Flow` containing `byte[]` or `ByteChunk` can be transformed by using `toByteFlow()` method. Any other flow can be
864+
transformed by using `toByteFlow()` with mapping function.
835865

836866
#### Text operations
867+
837868
* `encodeUtf8` encodes a `Flow<String>` into a `ByteFlow`
838-
* `linesUtf8` decodes a `ByteFlow` into a `Flow<String>`. Assumes that the input represents text with line breaks. The `String` elements emitted by resulting `Flow<String>` represent text lines.
839-
* `decodeStringUtf8` to decode a `ByteFlow` into a `Flow<String>`, without handling line breaks, just processing input bytes as UTF-8 characters, even if a multi-byte character is divided into two chunks.
869+
* `linesUtf8` decodes a `ByteFlow` into a `Flow<String>`. Assumes that the input represents text with line breaks. The
870+
`String` elements emitted by resulting `Flow<String>` represent text lines.
871+
* `decodeStringUtf8` to decode a `ByteFlow` into a `Flow<String>`, without handling line breaks, just processing input
872+
bytes as UTF-8 characters, even if a multi-byte character is divided into two chunks.
840873

841874
#### I/O Operations
875+
842876
* `runToInputStream(UnsupervisedScope scope)` runs given flow asynchronously into returned `InputStream`
843877
* `runToOutputStream(OutputStream outputStream)` runs given flow into provided `OutputStream`
844878
* `runToFile(Path path)` runs given flow into file. If file does not exist, it's created.
@@ -847,7 +881,8 @@ It is also possible to create Flow from `inputStream` or `path` using `Flows` fa
847881

848882
### Logging
849883

850-
Jox does not have any integrations with logging libraries, but it provides a simple way to log elements emitted by flows using the `.tap` method:
884+
Jox does not have any integrations with logging libraries, but it provides a simple way to log elements emitted by flows
885+
using the `.tap` method:
851886

852887
```java
853888
import com.softwaremill.jox.flows.Flows;
@@ -874,19 +909,18 @@ process. Hence, the scope should remain active as long as the publisher is used.
874909
Internally, elements emitted by the flow are buffered, using a buffer of capacity given by the `Channel.BUFFER_SIZE` in
875910
scope.
876911

877-
To obtain a `org.reactivestreams.Publisher` instance, you'll need to add the `reactive-streams` dependency and
912+
To obtain a `org.reactivestreams.Publisher` instance, you'll need to add the `reactive-streams` dependency and
878913
use `org.reactivestreams.FlowAdapters`.
879914

880-
881915
#### Publisher -> Flow
882916

883917
A `java.util.concurrent.Flow.Publisher` can be converted to a `Flow` using `Flow.fromPublisher`.
884918

885919
Internally, elements published to the subscription are buffered, using a buffer of capacity given by the
886920
`Channel.BUFFER_SIZE` in scope. That's also how many elements will be at most requested from the publisher at a time.
887921

888-
To convert a `org.reactivestreams.Publisher` instance, you'll need the same dependency as above and use `org.reactivestreams.FlowAdapters`.
889-
922+
To convert a `org.reactivestreams.Publisher` instance, you'll need the same dependency as above and use
923+
`org.reactivestreams.FlowAdapters`.
890924

891925
## Feedback
892926

channels/src/main/java/com/softwaremill/jox/Channel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ operations on these (previous) segments, and we'll end up wanting to remove such
9090
/**
9191
* Can be used with {@link Channel#withScopedBufferSize()} to pass buffer size value from scope.
9292
* e.g. `ScopedValues.where(BUFFER_SIZE, 8).run(() -> Channel.withScopedBufferSize())` will create a channel with buffer size = 8
93-
* **/
93+
**/
9494
public static final ScopedValue<Integer> BUFFER_SIZE = ScopedValue.newInstance();
9595
public static final int DEFAULT_BUFFER_SIZE = 16;
9696

channels/src/main/java/com/softwaremill/jox/ChannelClosed.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
*/
66
public sealed interface ChannelClosed permits ChannelDone, ChannelError {
77
ChannelClosedException toException();
8+
89
Channel<?> channel();
910
}

channels/src/main/java/com/softwaremill/jox/Segment.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.lang.invoke.MethodHandles;
44
import java.lang.invoke.VarHandle;
5-
import java.util.concurrent.atomic.AtomicInteger;
65

76
final class Segment {
87
static final int SEGMENT_SIZE = 32; // 2^5

channels/src/main/java/com/softwaremill/jox/Select.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public static <U> Object selectOrClosed(SelectClause<? extends U>... clauses) th
8585
// no clauses given
8686
throw new IllegalArgumentException("No clauses given");
8787
}
88-
if (Arrays.stream(clauses).anyMatch(Objects::isNull)){
88+
if (Arrays.stream(clauses).anyMatch(Objects::isNull)) {
8989
// null clauses given
9090
throw new IllegalArgumentException("Null clauses are not supported");
9191
}

channels/src/test/java/com/softwaremill/jox/ChannelInterruptionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import java.util.concurrent.ExecutionException;
88
import java.util.concurrent.Semaphore;
99

10-
import static java.util.concurrent.TimeUnit.SECONDS;
1110
import static com.softwaremill.jox.TestUtil.*;
11+
import static java.util.concurrent.TimeUnit.SECONDS;
1212
import static org.awaitility.Awaitility.await;
1313
import static org.junit.jupiter.api.Assertions.assertEquals;
1414

channels/src/test/java/com/softwaremill/jox/ChannelRendezvousTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
import java.util.HashSet;
77
import java.util.List;
88
import java.util.Set;
9-
import java.util.concurrent.*;
9+
import java.util.concurrent.ConcurrentLinkedQueue;
10+
import java.util.concurrent.ConcurrentSkipListSet;
11+
import java.util.concurrent.ExecutionException;
12+
import java.util.concurrent.Future;
1013

1114
import static com.softwaremill.jox.TestUtil.*;
12-
import static org.junit.jupiter.api.Assertions.*;
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
1317

1418
public class ChannelRendezvousTest {
1519
@Test

0 commit comments

Comments
 (0)