
org.dihedron.patterns.bus.AsynchronousBus Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dihedron-commons Show documentation
Show all versions of dihedron-commons Show documentation
Base set of functionalities, including simple utility classes and more complex patterns.
The newest version!
/*
* Copyright (c) 2012-2014, Andrea Funto'. All rights reserved. See LICENSE for details.
*/
package org.dihedron.patterns.bus;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.dihedron.core.License;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Andrea Funto'
*/
@License
public class AsynchronousBus extends Bus implements AutoCloseable {
/**
* The logger.
*/
private final static Logger logger = LoggerFactory.getLogger(AsynchronousBus.class);
/**
* The underlying thread pool.
*/
private ExecutorService executor;
/**
* Constructor; the underlying executor service is by default a cached thread
* pool for it seems to provide the best results with small asynchronous tasks.
*/
public AsynchronousBus() {
this(Executors.newCachedThreadPool());
}
/**
* Constructor.
*
* @param executor
* a user-provided executor service.
*/
public AsynchronousBus(ExecutorService executor) {
this.executor = executor;
}
/**
* @see org.dihedron.patterns.bus.Bus#send(java.lang.Object)
*/
@Override
public Bus send(M message) {
try {
final CompletionService completion = new ExecutorCompletionService(executor);
int submitted = 0;
for(Destination destination : destinations) {
++submitted;
logger.trace("sending message {} to destination {} in thread {}", message, destination, Thread.currentThread().getId());
completion.submit(new Task(destination, message));
}
int completed = 0;
boolean errors = false;
while(completed < submitted && !errors) {
Future result = completion.take(); //blocks if none available
try {
result.get();
++completed;
logger.trace("one task completed, {} out of {} so far", completed, submitted);
} catch(ExecutionException e) {
logger.error("one task failed", e);
errors = true;
}
}
} catch(InterruptedException e) {
logger.error("interrupted while waiting for destinations to handle their messages", e);
}
return this;
}
/**
* @see org.dihedron.patterns.bus.Bus#post(java.lang.Object)
*/
@Override
public Bus post(M message) {
final CompletionService completion = new ExecutorCompletionService(executor);
for(Destination destination : destinations) {
logger.trace("posting message {} to destination {} in thread {}", message, destination, Thread.currentThread().getId());
completion.submit(new Task(destination, message));
}
return this;
}
/**
* @see java.lang.AutoCloseable#close()
*/
@Override
public void close() {
this.executor.shutdown();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy