Skip to content

Commit

Permalink
Resolves checkstyle errors for guarded-suspension, half-sync-half-asy…
Browse files Browse the repository at this point in the history
…nc, hexagonal (#1064)

* Reduces checkstyle errors in guarded-suspension

* Reduces checkstyle errors in half-sync-half-async

* Reduces checkstyle errors in hexagonal
  • Loading branch information
anuragagarwal561994 authored and iluwatar committed Nov 10, 2019
1 parent 4f9ee01 commit dda0953
Show file tree
Hide file tree
Showing 34 changed files with 382 additions and 359 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@
* THE SOFTWARE.
*/

/**
* Guarded-suspension is a concurrent design pattern for handling situation when to execute some action we need
* condition to be satisfied.
* <p>
* Implementation is based on GuardedQueue, which has two methods: get and put,
* the condition is that we cannot get from empty queue so when thread attempt
* to break the condition we invoke Object's wait method on him and when other thread put an element
* to the queue he notify the waiting one that now he can get from queue.
*/
package com.iluwatar.guarded.suspension;

import java.util.concurrent.ExecutorService;
Expand All @@ -38,10 +29,18 @@

/**
* Created by robertt240 on 1/26/17.
*
* <p>Guarded-suspension is a concurrent design pattern for handling situation when to execute some
* action we need condition to be satisfied.
*
* <p>Implementation is based on GuardedQueue, which has two methods: get and put, the condition is
* that we cannot get from empty queue so when thread attempt to break the condition we invoke
* Object's wait method on him and when other thread put an element to the queue he notify the
* waiting one that now he can get from queue.
*/
public class App {
/**
* Example pattern execution
* Example pattern execution.
*
* @param args - command line args
*/
Expand All @@ -55,13 +54,15 @@ public static void main(String[] args) {
}
);

//here we wait two seconds to show that the thread which is trying to get from guardedQueue will be waiting
// here we wait two seconds to show that the thread which is trying
// to get from guardedQueue will be waiting
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//now we execute second thread which will put number to guardedQueue and notify first thread that it could get
// now we execute second thread which will put number to guardedQueue
// and notify first thread that it could get
executorService.execute(() -> {
guardedQueue.put(20);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@

package com.iluwatar.guarded.suspension;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedList;
import java.util.Queue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Guarded Queue is an implementation for Guarded Suspension Pattern
* Guarded suspension pattern is used to handle a situation when you want to execute a method
* on an object which is not in a proper state.
* Guarded Queue is an implementation for Guarded Suspension Pattern Guarded suspension pattern is
* used to handle a situation when you want to execute a method on an object which is not in a
* proper state.
*
* @see <a href="http://java-design-patterns.com/patterns/guarded-suspension/">http://java-design-patterns.com/patterns/guarded-suspension/</a>
*/
public class GuardedQueue {
Expand All @@ -44,6 +44,8 @@ public GuardedQueue() {
}

/**
* Get the last element of the queue is exists.
*
* @return last element of a queue if queue is not empty
*/
public synchronized Integer get() {
Expand All @@ -60,6 +62,8 @@ public synchronized Integer get() {
}

/**
* Put a value in the queue.
*
* @param e number which we want to put to our queue
*/
public synchronized void put(Integer e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,58 +23,50 @@

package com.iluwatar.halfsynchalfasync;

import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.LinkedBlockingQueue;

/**
*
* This application demonstrates Half-Sync/Half-Async pattern. Key parts of the pattern are
* {@link AsyncTask} and {@link AsynchronousService}.
*
* <p>
* <i>PROBLEM</i> <br>
* This application demonstrates Half-Sync/Half-Async pattern. Key parts of the pattern are {@link
* AsyncTask} and {@link AsynchronousService}.
*
* <p><i>PROBLEM</i> <br>
* A concurrent system have a mixture of short duration, mid duration and long duration tasks. Mid
* or long duration tasks should be performed asynchronously to meet quality of service
* requirements.
*
* <p>
* <i>INTENT</i> <br>
*
* <p><i>INTENT</i> <br>
* The intent of this pattern is to separate the the synchronous and asynchronous processing in the
* concurrent application by introducing two intercommunicating layers - one for sync and one for
* async. This simplifies the programming without unduly affecting the performance.
*
* <p>
* <i>APPLICABILITY</i> <br>
* UNIX network subsystems - In operating systems network operations are carried out
* asynchronously with help of hardware level interrupts.<br>
* CORBA - At the asynchronous layer one thread is associated with each socket that is connected
* to the client. Thread blocks waiting for CORBA requests from the client. On receiving request it
* is inserted in the queuing layer which is then picked up by synchronous layer which processes the
* request and sends response back to the client.<br>
* Android AsyncTask framework - Framework provides a way to execute long running blocking
* calls, such as downloading a file, in background threads so that the UI thread remains free to
* respond to user inputs.<br>
*
* <p>
* <i>IMPLEMENTATION</i> <br>
*
* <p><i>APPLICABILITY</i> <br>
* UNIX network subsystems - In operating systems network operations are carried out asynchronously
* with help of hardware level interrupts.<br> CORBA - At the asynchronous layer one thread is
* associated with each socket that is connected to the client. Thread blocks waiting for CORBA
* requests from the client. On receiving request it is inserted in the queuing layer which is then
* picked up by synchronous layer which processes the request and sends response back to the
* client.<br> Android AsyncTask framework - Framework provides a way to execute long running
* blocking calls, such as downloading a file, in background threads so that the UI thread remains
* free to respond to user inputs.<br>
*
* <p><i>IMPLEMENTATION</i> <br>
* The main method creates an asynchronous service which does not block the main thread while the
* task is being performed. The main thread continues its work which is similar to Async Method
* Invocation pattern. The difference between them is that there is a queuing layer between
* Asynchronous layer and synchronous layer, which allows for different communication patterns
* between both layers. Such as Priority Queue can be used as queuing layer to prioritize the way
* tasks are executed. Our implementation is just one simple way of implementing this pattern, there
* are many variants possible as described in its applications.
*
*/
public class App {

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

/**
* Program entry point
*
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
Expand All @@ -100,15 +92,13 @@ public static void main(String[] args) {
}

/**
*
* ArithmeticSumTask
*
* ArithmeticSumTask.
*/
static class ArithmeticSumTask implements AsyncTask<Long> {
private long n;
private long numberOfElements;

public ArithmeticSumTask(long n) {
this.n = n;
public ArithmeticSumTask(long numberOfElements) {
this.numberOfElements = numberOfElements;
}

/*
Expand All @@ -117,7 +107,7 @@ public ArithmeticSumTask(long n) {
*/
@Override
public Long call() throws Exception {
return ap(n);
return ap(numberOfElements);
}

/*
Expand All @@ -128,7 +118,7 @@ public Long call() throws Exception {
*/
@Override
public void onPreCall() {
if (n < 0) {
if (numberOfElements < 0) {
throw new IllegalArgumentException("n is less than 0");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* typically done is background threads and the result is posted back in form of callback. The
* callback does not implement {@code isComplete}, {@code cancel} as it is out of scope of this
* pattern.
*
*
* @param <O> type of result
*/
public interface AsyncTask<O> extends Callable<O> {
Expand All @@ -53,7 +53,7 @@ public interface AsyncTask<O> extends Callable<O> {
/**
* A callback called if computing the task resulted in some exception. This method is called when
* either of {@link #call()} or {@link #onPreCall()} throw any exception.
*
*
* @param throwable error cause
*/
void onError(Throwable throwable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@

package com.iluwatar.halfsynchalfasync;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is the asynchronous layer which does not block when a new request arrives. It just passes
Expand Down Expand Up @@ -63,13 +62,14 @@ public AsynchronousService(BlockingQueue<Runnable> workQueue) {

/**
* A non-blocking method which performs the task provided in background and returns immediately.
* <p>
* On successful completion of task the result is posted back using callback method
* {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally due to
* some exception then the reason for error is posted back using callback method
* {@link AsyncTask#onError(Throwable)}.
* <p>
* NOTE: The results are posted back in the context of background thread in this implementation.
*
* <p>On successful completion of task the result is posted back using callback method {@link
* AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally due to some
* exception then the reason for error is posted back using callback method {@link
* AsyncTask#onError(Throwable)}.
*
* <p>NOTE: The results are posted back in the context of background thread in this
* implementation.
*/
public <T> void execute(final AsyncTask<T> task) {
try {
Expand Down
57 changes: 26 additions & 31 deletions hexagonal/src/main/java/com/iluwatar/hexagonal/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,35 @@
import com.iluwatar.hexagonal.sampledata.SampleData;

/**
*
* Hexagonal Architecture pattern decouples the application core from the
* services it uses. This allows the services to be plugged in and the
* application will run with or without the services.<p>
*
* The core logic, or business logic, of an application consists of the
* algorithms that are essential to its purpose. They implement the use
* cases that are the heart of the application. When you change them, you
* change the essence of the application.<p>
*
* The services are not essential. They can be replaced without changing
* the purpose of the application. Examples: database access and other
* types of storage, user interface components, e-mail and other
* communication components, hardware devices.<p>
*
* This example demonstrates Hexagonal Architecture with a lottery system.
* The application core is separate from the services that drive it and
* from the services it uses.<p>
*
* The primary ports for the application are console interfaces
* {@link com.iluwatar.hexagonal.administration.ConsoleAdministration} through which the lottery round is
* initiated and run and {@link com.iluwatar.hexagonal.service.ConsoleLottery} that allows players to
* submit lottery tickets for the draw.<p>
*
* The secondary ports that application core uses are {@link com.iluwatar.hexagonal.banking.WireTransfers}
* which is a banking service, {@link com.iluwatar.hexagonal.eventlog.LotteryEventLog} that delivers
* eventlog as lottery events occur and {@link com.iluwatar.hexagonal.database.LotteryTicketRepository}
* that is the storage for the lottery tickets.
* Hexagonal Architecture pattern decouples the application core from the services it uses. This
* allows the services to be plugged in and the application will run with or without the services.
*
* <p>The core logic, or business logic, of an application consists of the algorithms that are
* essential to its purpose. They implement the use cases that are the heart of the application.
* When you change them, you change the essence of the application.
*
* <p>The services are not essential. They can be replaced without changing the purpose of the
* application. Examples: database access and other types of storage, user interface components,
* e-mail and other communication components, hardware devices.
*
* <p>This example demonstrates Hexagonal Architecture with a lottery system. The application core
* is separate from the services that drive it and from the services it uses.
*
* <p>The primary ports for the application are console interfaces {@link
* com.iluwatar.hexagonal.administration.ConsoleAdministration} through which the lottery round is
* initiated and run and {@link com.iluwatar.hexagonal.service.ConsoleLottery} that allows players
* to submit lottery tickets for the draw.
*
* <p>The secondary ports that application core uses are{@link
* com.iluwatar.hexagonal.banking.WireTransfers} which is a banking service, {@link
* com.iluwatar.hexagonal.eventlog.LotteryEventLog} that delivers eventlog as lottery events occur
* and {@link com.iluwatar.hexagonal.database.LotteryTicketRepository} that is the storage for the
* lottery tickets.
*/
public class App {

/**
* Program entry point
* Program entry point.
*/
public static void main(String[] args) {

Expand All @@ -73,11 +68,11 @@ public static void main(String[] args) {
// start new lottery round
LotteryAdministration administration = injector.getInstance(LotteryAdministration.class);
administration.resetLottery();

// submit some lottery tickets
LotteryService service = injector.getInstance(LotteryService.class);
SampleData.submitTickets(service, 20);

// perform lottery
administration.performLottery();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,28 @@
import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader;
import com.iluwatar.hexagonal.sampledata.SampleData;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Scanner;

/**
* Console interface for lottery administration
* Console interface for lottery administration.
*/
public class ConsoleAdministration {

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

/**
* Program entry point
* Program entry point.
*/
public static void main(String[] args) {
MongoConnectionPropertiesLoader.load();
Injector injector = Guice.createInjector(new LotteryModule());
LotteryAdministration administration = injector.getInstance(LotteryAdministration.class);
LotteryService service = injector.getInstance(LotteryService.class);
SampleData.submitTickets(service, 20);
ConsoleAdministrationSrv consoleAdministration = new ConsoleAdministrationSrvImpl(administration, LOGGER);
ConsoleAdministrationSrv consoleAdministration =
new ConsoleAdministrationSrvImpl(administration, LOGGER);
try (Scanner scanner = new Scanner(System.in)) {
boolean exit = false;
while (!exit) {
Expand Down

0 comments on commit dda0953

Please sign in to comment.