Skip to content

Commit

Permalink
Upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
jabrena committed May 27, 2024
1 parent 9fc08ca commit ae01b47
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 494 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A repository to review the main concepts about Functional Programming with Java.
```bash
sdk env install
./mvnw clean test -DexcludedGroups=performance,endtoend
./mvnw clean test -DexcludedGroups=performance,endtoend -Dtest=CFBasicsTest -pl training
./mvnw clean test -DexcludedGroups=performance,endtoend -Dtest=CFExamplesTest -pl training
./mvnw clean test -Dgroups=performance
./mvnw clean test -Dgroups=endtoend

Expand All @@ -24,14 +24,14 @@ sdk env install

## Functional programming features in Java

- Lambda Expressions
- Optionals
- Stream API
- CompletableFuture & Structural Concurrency
- Immutable Lists
- Sealed Classes
- Pattern Matching for Switch
- Records & Record Patterns
- [ ] Lambda Expressions
- [ ] Optionals
- [ ] Stream API
- [x] CompletableFuture & [ ] Structural Concurrency
- [ ] Immutable Lists
- [ ] Sealed Classes
- [ ] Pattern Matching for Switch
- [ ] Records & Record Patterns

## Functional programming timeline in Java

Expand Down
108 changes: 49 additions & 59 deletions training/src/main/java/info/jab/fp/async/CFExamples.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,6 @@ public Integer callingFourAsyncTasks() {
.reduce(0 , (i1, i2) -> i1 + i2);
}

CompletableFuture<Optional<Integer>> asyncCallOptional(Integer param) {
CompletableFuture<Optional<Integer>> cf1 = CompletableFuture
.supplyAsync(() -> Optional.of(this.compute.apply(param)));
return cf1;
}

CompletableFuture<Integer> asyncCallFailed() {
CompletableFuture<Integer> cf1 = CompletableFuture
.supplyAsync(() -> {
Expand All @@ -104,51 +98,22 @@ CompletableFuture<Integer> asyncCallFailed() {
return cf1;
}

CompletableFuture<Integer> asyncCallFailedProtected() {
CompletableFuture<Integer> cf1 = CompletableFuture
.supplyAsync(() -> {
throw new RuntimeException("Katakroker");
})
.handle((result, ex) -> {
return 100;
});
return cf1;
}

Supplier<Integer> katakroker = () -> {
delay(1);
throw new RuntimeException("Katakroker");
};

CompletableFuture<Optional<Integer>> asyncCallFailedOptional() {
CompletableFuture<Optional<Integer>> cf1 = CompletableFuture
.supplyAsync(() -> Optional.of(katakroker.get()));
return cf1;
}

public Integer myForthCF() {
public Integer callingFourAsyncTasksAndOneFails() {

CompletableFuture<Integer> request1 = asyncCall(1);
CompletableFuture<Integer> request2 = asyncCallFailed();
CompletableFuture<Integer> request3 = asyncCall(1);
CompletableFuture<Integer> request4 = asyncCall(1);

List<CompletableFuture<Integer>> futuresList = List.of(request1, request2, request3);
List<CompletableFuture<Integer>> futuresList = List.of(request1, request2, request3, request4);

return futuresList.stream()
.filter(cf -> !cf.isCompletedExceptionally())
.map(CompletableFuture::join)
.reduce(0 , (i1, i2) -> i1 + i2);
}

/**
* If an exception occurs in a stage and we do not do anything
* to handle that exception then execution to the further stages is abandon.
*
* @return
*/
public Integer myFifthCF() {

logger.info("Defining");
public Integer callingFourAsyncTasksAndThreeFails() {

CompletableFuture<Integer> request1 = asyncCallFailed();
CompletableFuture<Integer> request2 = asyncCallFailed();
Expand All @@ -157,38 +122,56 @@ public Integer myFifthCF() {

List<CompletableFuture<Integer>> futuresList = List.of(request1, request2, request3, request4);

logger.info("Running");

var futuresList2 = Stream.of(request1, request2, request3, request4);


return futuresList2
return futuresList.stream()
.filter(not(CompletableFuture::isCompletedExceptionally))
.map(CompletableFuture::join)
.reduce(0 , (i1, i2) -> i1 + i2);
}

public Integer mySixthCF() {
CompletableFuture<Integer> asyncCallFailedWithDefaultResult() {
CompletableFuture<Integer> cf1 = CompletableFuture
.supplyAsync(() -> {
throw new RuntimeException("Katakroker");
})
.handle((result, ex) -> {
return 100;
});
return cf1;
}

logger.info("Defining");
public Integer callingFourAsyncTasksWithDefaultValues() {

CompletableFuture<Integer> request1 = asyncCall(1);
CompletableFuture<Integer> request2 = asyncCallFailed();
CompletableFuture<Integer> request3 = asyncCallFailedProtected();

List<CompletableFuture<Integer>> futuresList = List.of(request1, request2, request3);
CompletableFuture<Integer> request2 = asyncCall(1);
CompletableFuture<Integer> request3 = asyncCallFailed();
CompletableFuture<Integer> request4 = asyncCallFailedWithDefaultResult();

logger.info("Running");
List<CompletableFuture<Integer>> futuresList = List.of(request1, request2, request3, request4);

return futuresList.stream()
.filter(not(CompletableFuture::isCompletedExceptionally))
.map(CompletableFuture::join)
.reduce(0 , (i1, i2) -> i1 + i2);
}

public Integer mySeventhCF() {
CompletableFuture<Optional<Integer>> asyncCallOptional(Integer param) {
CompletableFuture<Optional<Integer>> cf1 = CompletableFuture
.supplyAsync(() -> Optional.of(this.compute.apply(param)));
return cf1;
}

Supplier<Integer> katakroker = () -> {
delay(1);
throw new RuntimeException("Katakroker");
};

logger.info("Defining");
CompletableFuture<Optional<Integer>> asyncCallFailedOptional() {
CompletableFuture<Optional<Integer>> cf1 = CompletableFuture
.supplyAsync(() -> Optional.of(katakroker.get()));
return cf1;
}

public Integer callingFourAsyncTasksWithOptionals() {

CompletableFuture<Optional<Integer>> request1 = asyncCallOptional(1);
CompletableFuture<Optional<Integer>> request2 = asyncCallFailedOptional();
Expand All @@ -197,12 +180,19 @@ public Integer mySeventhCF() {

List<CompletableFuture<Optional<Integer>>> futuresList = List.of(request1, request2, request3, request4);

logger.info("Running");

return futuresList.stream()
.filter(CompletableFuture::isCompletedExceptionally)
.map(cf -> cf.handle((result, ex) -> {
if (ex != null) {
// Log the exception if needed
System.out.println("Exception: " + ex.getMessage());
return Optional.<Integer>empty();
} else {
return result;
}
}))
.map(CompletableFuture::join)
.map(o -> o.get())
.reduce(0 , (i1, i2) -> i1 + i2);
.filter(Optional::isPresent)
.map(Optional::get)
.reduce(0, Integer::sum);
}
}
12 changes: 5 additions & 7 deletions training/src/main/java/info/jab/fp/async/CoresDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

public class CoresDemo {

private static final Logger LOGGER = LoggerFactory.getLogger(CoresDemo.class);
private static final Logger logger = LoggerFactory.getLogger(CoresDemo.class);

public static void main(String... args) {

Expand All @@ -27,7 +27,7 @@ public static void main(String... args) {
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;

LOGGER.info("{}", elapsedTime);
logger.info("{}", elapsedTime);
};

Supplier<Integer> process = () -> {
Expand Down Expand Up @@ -56,10 +56,8 @@ static class Client {

private int x;

Logger LOGGER = LoggerFactory.getLogger(Client.class);

public Client(int x) {
LOGGER.info("new Instance: {}", x);
logger.info("new Instance: {}", x);
this.x = x;
}

Expand All @@ -70,14 +68,14 @@ CompletableFuture<Integer> runAsync() {
.orTimeout(60, TimeUnit.SECONDS)
.handle((response, ex) -> {
if (!Objects.isNull(ex)) {
LOGGER.error(ex.getLocalizedMessage(), ex);
logger.error(ex.getLocalizedMessage(), ex);
}
return response;
});
}

private Integer longProcess() {
LOGGER.info("Running: {}", this.x);
logger.info("Running: {}", this.x);
sleep(2);
return 0;
}
Expand Down
50 changes: 0 additions & 50 deletions training/src/main/java/info/jab/fp/async/SimpleCurl.java

This file was deleted.

62 changes: 0 additions & 62 deletions training/src/main/java/info/jab/fp/async/WebAddressService.java

This file was deleted.

Loading

0 comments on commit ae01b47

Please sign in to comment.