deps: Refactor dependencies (#3224)

* remove spring dep
move junit, logging, mockito under dep mgmt

* upgrade anti-corruption-layer deps

* async method invocation

* balking, bloc

* bridge to bytecode

* caching

* callback - cqrs

* component - health check

* hexagonal - metadata mapping

* rest of the patterns

* remove checkstyle, take spotless into use
This commit is contained in:
Ilkka Seppälä authored and GitHub committed 2025-03-29 19:34:27 +02:00
1 parent 371439aeaa
commit 0ca162a55c
1863 files changed
+14403 -17632

No files matched your search

+27
View File
@@ -34,10 +34,37 @@
</parent>
<artifactId>leader-followers</artifactId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<mainClass>com.iluwatar.leaderfollowers.App</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -39,27 +39,23 @@ import java.util.concurrent.TimeUnit;
* work. {@link TaskSet} basically acts as the source of input events for the {@link Worker}, who
* are spawned and controlled by the {@link WorkCenter} . When {@link Task} arrives then the leader
* takes the work and calls the {@link TaskHandler}. It also calls the {@link WorkCenter} to
* promotes one of the followers to be the new leader, who can then process the next work and so
* on.
* promotes one of the followers to be the new leader, who can then process the next work and so on.
*
* <p>The pros for this pattern are:
* It enhances CPU cache affinity and eliminates unbound allocation and data buffer sharing between
* threads by reading the request into buffer space allocated on the stack of the leader or by using
* the Thread-Specific Storage pattern [22] to allocate memory. It minimizes locking overhead by not
* exchanging data between threads, thereby reducing thread synchronization. In bound handle/thread
* associations, the leader thread dispatches the event based on the I/O handle. It can minimize
* priority inversion because no extra queuing is introduced in the server. It does not require a
* context switch to handle each event, reducing the event dispatching latency. Note that promoting
* a follower thread to fulfill the leader role requires a context switch. Programming simplicity:
* The Leader/Followers pattern simplifies the programming of concurrency models where multiple
* threads can receive requests, process responses, and de-multiplex connections using a shared
* handle set.
* <p>The pros for this pattern are: It enhances CPU cache affinity and eliminates unbound
* allocation and data buffer sharing between threads by reading the request into buffer space
* allocated on the stack of the leader or by using the Thread-Specific Storage pattern [22] to
* allocate memory. It minimizes locking overhead by not exchanging data between threads, thereby
* reducing thread synchronization. In bound handle/thread associations, the leader thread
* dispatches the event based on the I/O handle. It can minimize priority inversion because no extra
* queuing is introduced in the server. It does not require a context switch to handle each event,
* reducing the event dispatching latency. Note that promoting a follower thread to fulfill the
* leader role requires a context switch. Programming simplicity: The Leader/Followers pattern
* simplifies the programming of concurrency models where multiple threads can receive requests,
* process responses, and de-multiplex connections using a shared handle set.
*/
public class App {
/**
* The main method for the leader followers pattern.
*/
/** The main method for the leader followers pattern. */
public static void main(String[] args) throws InterruptedException {
var taskSet = new TaskSet();
var taskHandler = new TaskHandler();
@@ -68,9 +64,7 @@ public class App {
execute(workCenter, taskSet);
}
/**
* Start the work, dispatch tasks and stop the thread pool at last.
*/
/** Start the work, dispatch tasks and stop the thread pool at last. */
private static void execute(WorkCenter workCenter, TaskSet taskSet) throws InterruptedException {
var workers = workCenter.getWorkers();
var exec = Executors.newFixedThreadPool(workers.size());
@@ -81,9 +75,7 @@ public class App {
exec.shutdownNow();
}
/**
* Add tasks.
*/
/** Add tasks. */
private static void addTasks(TaskSet taskSet) throws InterruptedException {
var rand = new SecureRandom();
for (var i = 0; i < 5; i++) {
@@ -27,17 +27,12 @@ package com.iluwatar.leaderfollowers;
import lombok.Getter;
import lombok.Setter;
/**
* A unit of work to be processed by the Workers.
*/
/** A unit of work to be processed by the Workers. */
public class Task {
@Getter
private final int time;
@Getter private final int time;
@Getter
@Setter
private boolean finished;
@Getter @Setter private boolean finished;
public Task(int time) {
this.time = time;
@@ -26,15 +26,11 @@ package com.iluwatar.leaderfollowers;
import lombok.extern.slf4j.Slf4j;
/**
* The TaskHandler is used by the {@link Worker} to process the newly arrived task.
*/
/** The TaskHandler is used by the {@link Worker} to process the newly arrived task. */
@Slf4j
public class TaskHandler {
/**
* This interface handles one task at a time.
*/
/** This interface handles one task at a time. */
public void handleTask(Task task) throws InterruptedException {
var time = task.getTime();
Thread.sleep(time);
@@ -27,9 +27,7 @@ package com.iluwatar.leaderfollowers;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* A TaskSet is a collection of the tasks, the leader receives task from here.
*/
/** A TaskSet is a collection of the tasks, the leader receives task from here. */
public class TaskSet {
private final BlockingQueue<Task> queue = new ArrayBlockingQueue<>(100);
@@ -35,13 +35,10 @@ import lombok.Getter;
*/
public class WorkCenter {
@Getter
private Worker leader;
@Getter private Worker leader;
private final List<Worker> workers = new CopyOnWriteArrayList<>();
/**
* Create workers and set leader.
*/
/** Create workers and set leader. */
public void createWorkers(int numberOfWorkers, TaskSet taskSet, TaskHandler taskHandler) {
for (var id = 1; id <= numberOfWorkers; id++) {
var worker = new Worker(id, this, taskSet, taskHandler);
@@ -58,9 +55,7 @@ public class WorkCenter {
workers.remove(worker);
}
/**
* Promote a leader.
*/
/** Promote a leader. */
public void promoteLeader() {
Worker leader = null;
if (!workers.isEmpty()) {
@@ -27,22 +27,17 @@ package com.iluwatar.leaderfollowers;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
/**
* Worker class that takes work from work center.
*/
/** Worker class that takes work from work center. */
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Slf4j
public class Worker implements Runnable {
@EqualsAndHashCode.Include
private final long id;
@EqualsAndHashCode.Include private final long id;
private final WorkCenter workCenter;
private final TaskSet taskSet;
private final TaskHandler taskHandler;
/**
* Constructor to create a worker which will take work from the work center.
*/
/** Constructor to create a worker which will take work from the work center. */
public Worker(long id, WorkCenter workCenter, TaskSet taskSet, TaskHandler taskHandler) {
super();
this.id = id;
@@ -83,5 +78,4 @@ public class Worker implements Runnable {
}
}
}
}
@@ -28,14 +28,11 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;
/**
* Application test
*/
/** Application test */
class AppTest {
@Test
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
assertDoesNotThrow(() -> App.main(new String[] {}));
}
}
@@ -28,9 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/**
* Tests for TaskHandler
*/
/** Tests for TaskHandler */
class TaskHandlerTest {
@Test
@@ -40,5 +38,4 @@ class TaskHandlerTest {
taskHandler.handleTask(handle);
assertTrue(handle.isFinished());
}
}
@@ -28,9 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Tests for TaskSet
*/
/** Tests for TaskSet */
class TaskSetTest {
@Test
@@ -48,5 +46,4 @@ class TaskSetTest {
assertEquals(100, task.getTime());
assertEquals(0, taskSet.getSize());
}
}
@@ -29,9 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
/**
* Tests for WorkCenter
*/
/** Tests for WorkCenter */
class WorkCenterTest {
@Test