1

I have two process ProcessA and ProcessB. I want to run these two process independent of each other. There is no relation between them at all.

  • Each process should have a different Properties object.
  • Each process should have a different thread pool configuration since they can be run in multithreaded way if needed independent of other process.

Below is my design:

Process class (abstract):

public abstract class Process implements Runnable {
  private final Properties props;
  private final String processName;

  public Process(String processName, Properties props) {
    this.processName = processName;
    this.props = props;
  }

  public abstract void shutdown();
}

ProcessA class:

public class ProcessA implements Process {

  public ProcessA(String processName, Properties props) {
    super(processName, props);
  }

  @Override
  public void run() {
    // add run code here
    // all the logic of executing my process comes here
    // here it uses "processName" and "props" object to do certain things
  }

  @Override
  public void shutdown() {
    // shut down code
  }
}

Process B class:

// similar to `ProcessA` but with specific details of B

ProcessHandler class (abstract):

public abstract class ProcessHandler {
  private final ExecutorService executorServiceProcess;
  private final List<Process> processList;
  private final int poolSize;

  protected ProcessHandler(int poolSize) {
    this.executorServiceProcess = Executors.newFixedThreadPool(poolSize);
    this.processList = new ArrayList<>();
    this.poolSize = poolSize;
  }

  public void postInit(Process process) {
    for (int i = 0; i < poolSize; i++) {
      processList.add(process);
      executorServiceProcess.submit(process);
    }
  }

  public void shutdown() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        for (Process process : processList) {
          process.shutdown();
        }
        executorServiceProcess.shutdown();
        try {
          executorServiceProcess.awaitTermination(1000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
          Thread.currentThread().interrupt();
        }
      }
    });
  }
}

ProcessHandlerA class:

public class ProcessHandlerA extends ProcessHandler {

  public ProcessHandlerA() {
    super(3);// configure pool size properly w.r.to ProcessA
  }

  public void postInit() {
    ProcessA processA = new ProcessA("processA", properties);
    super(processA);
  }

  public void shutdown() {
    super.shutdown();
  }
}

ProcessHandlerB class:

// similar to ProcessHandlerA but with specific details for B

Below is my main class in one of my project where I execute my ProcessA and ProcessB.

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;

@Singleton
@DependencyInjectionInitializer
public class Initializer {

  @Inject
  private ProcessHandlerA processHandlerA;

  @Inject
  private ProcessHandlerB processHandlerB;

  @PostConstruct
  public void init() {
    processHandlerA.postInit();
    ProcessHandlerB.postInit();
  }

  @PreDestroy
  public void shutdown() {
    processHandlerB.shutdown();
    processHandlerB.shutdown();
  }
}

And in some other project my main class will be:

public class Initializer {

  public static void main(String[] args) {
    // call both processes from here
  }
}

Is this the right design for this kind of problem? Let me know if there is any better and efficient way to solve this problem.

8
  • Add more background. Launching tasks is trivial, what do you need to achieve?
    – Basilevs
    Commented Nov 28, 2016 at 1:26
  • They all are Kafka consumers listening to Kafka and on those events I do all kind of manipulations and all these things happens in my run method of each process and after that I send it to some other system.
    – david
    Commented Nov 28, 2016 at 1:29
  • BTW, name process is misleading, yours are not native processes.
    – Basilevs
    Commented Nov 28, 2016 at 1:30
  • Yeah I agree. I just wanted to make problem simpler for design that's why I made it like that. As you can see in my abstract class ProcessHandler I have shutdown method which will shutdown all my processes.
    – david
    Commented Nov 28, 2016 at 1:32
  • Why a single pool won't do? You could add both tasks there to avoid extra management.
    – Basilevs
    Commented Nov 28, 2016 at 1:32

1 Answer 1

1

This question is more suited for Code Review.

Your solution is fine, but you overuse inheritance and DI. Adding a process constructor argument to ProcessHandler and removing postInit method, would make ProcessHandler permanently consistent and prevent a need of extending it for each new Process.

public final class ProcessHandler {
  private final ExecutorService executorServiceProcess;
  private final Process process;

  public ProcessHandler(Process process, int poolSize) {
    this.executorServiceProcess = Executors.newFixedThreadPool(poolSize);
    this.process = process;
    for (int i = 0; i < poolSize; i++) {
      executorServiceProcess.submit(process);
    }
 }
  public void shutdown() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        executorServiceProcess.shutdown();
        process.shutdown ();
        try {
          executorServiceProcess.awaitTermination(1000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
          Thread.currentThread().interrupt();
        }
      }
    });
  }
}

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;

@Singleton
@DependencyInjectionInitializer
public class Initializer {

  // Use named injections, optionally
  private final ProcessHandler processHandlerA = new ProcessHandler (new ProcessA(), 3);
  private final ProcessHandler processHandlerB = new ProcessHandler (new ProcessB(), 3);

  @PreDestroy
  public void shutdown() {
    processHandlerB.shutdown();
    processHandlerB.shutdown();
  }
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.