Handling multiple errors from thread workers - java

I spawn worker threads to do job:
List<Future<WorkerInfo>> futures = new ArrayList<>();
for (int i = 0; i < numOfUsers; i++) {
Future<WorkerInfo> future = threadExecutor.submit(() -> runLoad(arguments));
futures.add(future);
}
Now runLoad(..) function returns the state of the worker:
private WorkerInfo runLoad(int load,...) {
// start of the load
long start = System.currentTimeMillis();
Thread.currentThread().setName("LoadWorker with load: " + load);
try {
for (int i = 0; i < load; i++) {
// do something
}
long end = System.currentTimeMillis() - start;
return WorkerInfo .success(load, end);
} catch (IOException e) {
long end = System.currentTimeMillis() - start;
return new WorkerInfo (load, end, e.getMessage(), e);
}
}
The WorkerInfo class is simple class holding data:
public class WorkerInfo {
private final int load;
private final long time;
private final String message;
private final Throwable error;
public WorkerInfo (int load, long time, String message, Throwable error) {
this.load = load;
this.time = time;
this.message = message;
this.error = error;
}
public static WorkerInfo success(int load, long end) {
return new WorkerInfo(load,end,"",null);
}
public boolean hasError(){
return error != null;
}
public int getLoad() {
return load;
}
public String getMessage() {
return message;
}
public Throwable getError() {
return error;
}
}
Now i want to check if there was any error after the execution has finnished.
private void checkError(List<Future<WorkerInfo>> futures) {
List<String> errors = new ArrayList<>();
for (Future<WorkerInfo > future : futures) {
WorkerInfo workerInfo = unpackFuture(future);
if (workerInfo .hasError()) {
String message = workerInfo .getMessage();
errors.add(message);
}
}
if (!errors.isEmpty()) {
// what to throw here?
}
}
WHat is the best practice when multiple worker throw error? Lets say i am running 6 workers and 4 of them end with error. What error message should i throw then? What is the best way to aggregate the error messages into one? Or how to handle this?
Thanks for help!

Related

Hystrix Circuit Breaker won't open?

I'm trying to learn how to use Hystrix. I've created this class below:
public class CommandReturnAllExceptFive extends HystrixCommand<Integer> {
public static final Integer SLEEP_TIME = 5000;
private Integer x;
public CommandReturnAllExceptFive(Integer x) {
super(getHystrixConfiguration());
this.x = x;
System.out.println("Is circuit breaker open? " + (this.circuitBreaker.isOpen() ? "yes" : "no"));
System.out.println("Requests so far: "+(this.metrics.getRollingCount(HystrixEventType.FAILURE)));
}
public void setX(Integer x) {
this.x = x;
}
private static HystrixCommand.Setter getHystrixConfiguration() {
HystrixCommandProperties.Setter properties
= HystrixCommandProperties.Setter()
.withCircuitBreakerSleepWindowInMilliseconds(SLEEP_TIME)
.withCircuitBreakerEnabled(true)
.withCircuitBreakerRequestVolumeThreshold(1)
.withCircuitBreakerErrorThresholdPercentage(1)
.withMetricsRollingStatisticalWindowBuckets(1)
.withMetricsRollingStatisticalWindowBuckets(1);
HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("ReturnAllExceptFive");
return HystrixCommand.Setter.withGroupKey(groupKey).andCommandPropertiesDefaults(properties);
}
protected Integer run() throws Exception {
if (x == 5) {
throw new Exception();
}
return x;
}
}
with the following unit test:
#Test
public void testCommandReturnAllExceptFive_doesStallBeforeCallingAgain() {
boolean exceptionIsThrown = false;
try {
CommandReturnAllExceptFive returnAllExceptFive = new CommandReturnAllExceptFive(5);
returnAllExceptFive.execute();
} catch (Exception ex) {
exceptionIsThrown = true;
}
assertThat(exceptionIsThrown, is(true));
long timeNow = System.currentTimeMillis();
boolean callIsSuccessful = false;
while (!callIsSuccessful) {
try {
CommandReturnAllExceptFive returnAllExceptFive = new CommandReturnAllExceptFive(1);
returnAllExceptFive.execute();
callIsSuccessful = true;
} catch (Exception ex) {
}
}
long timeAfter = System.currentTimeMillis();
long timeToSuccess = timeAfter - timeNow;
System.out.println("timeNow: "+timeNow+"\ntimeAfter: "+timeAfter);
//assertThat(timeToSuccess >= CommandReturnAllExceptFive.SLEEP_TIME, is(true));
}
which is basically verifying that the call fails at 5, and that it does stall for the specified period of time after a successful execution. The debugging statements indicate that the circuit is never closed, but it should be closed after the first call since that one throws an exception, hence indicating failure. Can anyone help me out here?

Is there any alternate way to enable Multithreading without using Join in my below code

Currently I am using join() to join my current thread. As far as i know join will make it plain sequential code. I want to do it in multithreading.
public class A {
private static final Logger logger = LoggerFactory.getLogger(A.class);
#Value("${query.interval}")
private String queryInterval;
private Set<B> missingKeys = new HashSet<>();
private Map<E, String> erroredKeys;
public Map<B, Collection<Product>> methodA(
List<B> searchKeyList) {
long startTime = System.currentTimeMillis();
missingKeys = new HashSet<>();
erroredKeys = new HashMap<>();
int size = searchKeyList.size();
int threadNumber = 0;
int startIndex = 0;
int endIndex = 0;
List<C> c = new ArrayList<>();
int qrySize = Integer.parseInt(queryInterval);
logger.info("Size of searchKeyList [{}] of instrument look up", new Object[] { searchKeyList.size() });
for (; threadNumber < size / rdsQrySize; threadNumber++) {
startIndex = threadNumber * rdsQrySize;
endIndex = startIndex + rdsQrySize;
logger.debug("Creating thread for Instrument LookUp");
c = createThread(threadNumber, startIndex, endIndex,
searchKeyList, c);
}
if (size % rdsQrySize != 0) {
startIndex = threadNumber * rdsQrySize;
endIndex = startIndex + size % rdsQrySize;
logger.debug("Creating EXTRA thread for Instrument LookUp");
c = createThread(requestor, businessLine, resolutionEnum, threadNumber, startIndex, endIndex,
searchKeyList, c);
}
// Here I don't want to use join. I am looking for any other way to do this
// to make my code run in multithreaded way
for (C lookUpThread : c) {
try {
lookUpThread.join();
} catch (InterruptedException e) {
}
}
Map<B, Collection<Product>> responseDataList = new HashMap<>();
for (C lookUpThread : c) {
Map<B, Collection<Product>> instrumentResponseData = lookUpThread.getInstrumentResponse()
.getFoundData();
missingKeys.addAll(lookUpThread.getInstrumentResponse().getMissingKeys());
erroredKeys.putAll(lookUpThread.getInstrumentResponse().getErroredKeys());
responseDataList.putAll(instrumentResponseData);
}
long stopTime = System.currentTimeMillis();
logger.info(
"[{}] milliseconds taken to fetch [{}] instruments from RDS divided in [{}] threads ",
new Object[] { stopTime - startTime,size, c.size() });
return responseDataList;
}
private List<C> createThread(int threadNumber, int startIndex, int endIndex,
List<B> searchKeyList, List<C> c) {
List<B> searchKeys = new ArrayList<>();
for (; startIndex < endIndex; startIndex++) {
searchKeys.add(searchKeyList.get(startIndex));
}
ProductRequest<B> request = new ProductRequest<>(
searchKeys);
logger.info("Creating thread no [{}] for Instrument LookUp", new Object[]{threadNumber});
C lookUpThread = new C("RDS Instrument Thread - " + threadNumber);
lookUpThread.setRequest(request);
lookUpThread.start();
c.add(lookUpThread);
return c;
}
public Set<B> getMissingKeys() {
return missingKeys;
}
public void setMissingKeys(Set<B> missingKeys) {
this.missingKeys = missingKeys;
}
public Map<E, String> getErroredKeys() {
return erroredKeys;
}
public void setErroredKeys(Map<E, String> erroredKeys) {
this.erroredKeys = erroredKeys;
}
// Inner class for thread
private class C extends Thread {
ClientResponse<B, Product, E> instrumentResponse = null;
ProductRequest<B> request = null;
C(String name) {
super.setName(name);
}
public void run() {
long startTime = System.currentTimeMillis();
instrumentResponse = rdsDao.getByKey(request);
long stopTime = System.currentTimeMillis();
logger.info("RDS responded in [{}] milliseconds for thread [{}] while Instrument Lookup",
new Object[] { stopTime - startTime, super.getName() });
}
public void setInstrumentResponse(
ClientResponse<B, Product, E> instrumentResponse) {
this.instrumentResponse = instrumentResponse;
}
public ClientResponse<B, Product, E> getInstrumentResponse() {
return instrumentResponse;
}
public void setRequest(ProductRequest<B> request) {
this.request = request;
}
public ProductRequest<B> getRequest() {
return request;
}
}
}
Your code is running concurrently (not sequentially as you mentioned).
ThreadT.join() will make the current thread to wait for the ThreadT to finish.
As you are spawning multiple threads, and joining with the Main thread, those non Main threads will still run concurrently (as you are calling Thread.start() in createThread()).
If you are not joining the non Main threads as above, then your Main thread/method will complete before those other non Main threads complete, which I guess is not desirable for you.

How do we know threadPoolExecutor has finished execution

I have a parent thread that sends messages to MQ and it manages a ThreadPoolExecutor for worker threads which listen to MQ and writes message to output file. I manage a threadpool of size 5. So when I run my program, I have 5 files with messages. Everything works fine until here. I now need to merge these 5 files in my parent thread.
How do I know ThreadPoolExecutor finished processing so I can start merging files.
public class ParentThread {
private MessageSender messageSender;
private MessageReciever messageReciever;
private Queue jmsQueue;
private Queue jmsReplyQueue;
ExecutorService exec = Executors.newFixedThreadPool(5);
public void sendMessages() {
System.out.println("Sending");
File xmlFile = new File("c:/filename.txt");
List<String> lines = null;
try {
lines = FileUtils.readLines(xmlFile, null);
} catch (IOException e) {
e.printStackTrace();
}
for (String line : lines){
messageSender.sendMessage(line, this.jmsQueue, this.jmsReplyQueue);
}
int count = 0;
while (count < 5) {
messageSender.sendMessage("STOP", this.jmsQueue, this.jmsReplyQueue);
count++;
}
}
public void listenMessages() {
long finishDate = new Date().getTime();
for (int i = 0; i < 5; i++) {
Worker worker = new Worker(i, this.messageReciever, this.jmsReplyQueue);
exec.execute(worker);
}
exec.shutdown();
if(exec.isTerminated()){ //PROBLEM is HERE. Control Never gets here.
long currenttime = new Date().getTime() - finishDate;
System.out.println("time taken: "+currenttime);
mergeFiles();
}
}
}
This is my worker class
public class Worker implements Runnable {
private boolean stop = false;
private MessageReciever messageReciever;
private Queue jmsReplyQueue;
private int processId;
private int count = 0;
private String message;
private File outputFile;
private FileWriter outputFileWriter;
public Worker(int processId, MessageReciever messageReciever,
Queue jmsReplyQueue) {
this.processId = processId;
this.messageReciever = messageReciever;
this.jmsReplyQueue = jmsReplyQueue;
}
public void run() {
openOutputFile();
listenMessages();
}
private void listenMessages() {
while (!stop) {
String message = messageReciever.receiveMessage(null,this.jmsReplyQueue);
count++;
String s = "message: " + message + " Recieved by: "
+ processId + " Total recieved: " + count;
System.out.println(s);
writeOutputFile(s);
if (StringUtils.isNotEmpty(message) && message.equals("STOP")) {
stop = true;
}
}
}
private void openOutputFile() {
try {
outputFile = new File("C:/mahi/Test", "file." + processId);
outputFileWriter = new FileWriter(outputFile);
} catch (IOException e) {
System.out.println("Exception while opening file");
stop = true;
}
}
private void writeOutputFile(String message) {
try {
outputFileWriter.write(message);
outputFileWriter.flush();
} catch (IOException e) {
System.out.println("Exception while writing to file");
stop = true;
}
}
}
How will I know when the ThreadPool has finished processing so I can do my other clean up work?
Thanks
If you Worker class implements Callable instead of Runnable, then you'd be able to see when your threads complete by using a Future object to see if the Thread has returned some result (e.g. boolean which would tell you whether it has finished execution or not).
Take a look in section "8. Futures and Callables" # website below, it has exactly what you need imo:
http://www.vogella.com/articles/JavaConcurrency/article.html
Edit: So after all of the Futures indicate that their respective Callable's execution is complete, its safe to assume your executor has finished execution and can be shutdown/terminated manually.
Something like this:
exec.shutdown();
// waiting for executors to finish their jobs
while (!exec.awaitTermination(50, TimeUnit.MILLISECONDS));
// perform clean up work
You can use a thread for monitoring ThreadPoolExecutor like that
import java.util.concurrent.ThreadPoolExecutor;
public class MyMonitorThread implements Runnable {
private ThreadPoolExecutor executor;
private int seconds;
private boolean run=true;
public MyMonitorThread(ThreadPoolExecutor executor, int delay)
{
this.executor = executor;
this.seconds=delay;
}
public void shutdown(){
this.run=false;
}
#Override
public void run()
{
while(run){
System.out.println(
String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
this.executor.getPoolSize(),
this.executor.getCorePoolSize(),
this.executor.getActiveCount(),
this.executor.getCompletedTaskCount(),
this.executor.getTaskCount(),
this.executor.isShutdown(),
this.executor.isTerminated()));
try {
Thread.sleep(seconds*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And add
MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
Thread monitorThread = new Thread(monitor);
monitorThread.start();
to your class where ThreadPoolExecutor is located.
It will show your threadpoolexecutors states in every 3 seconds.

Application hangs for few minutes even after all the threads are done

I converted a working Producer/Consumer Example from Thread/Runnable to Executor/Callable/BlockingQueues and using the Poison Pill termination pattern.
If you run the program below, it will hang for few minutes even though every thread has completed.
jstack shows numerous threads blocked on a queue that is not seemingly related to the application.
"pool-1-thread-10" prio=5 tid=10b08d000 nid=0x10d91c000 waiting on condition [10d91b000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <7f3113510> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:680)
I can not figure out why the application hangs. Any help is appreciated.
Thank you
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
public class ProducersConsumers {
private LinkedBlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
private static final ExecutorService executorPool = Executors.newCachedThreadPool();
private Random randGenerator = new Random(System.currentTimeMillis());
private class Item {
private boolean done = false;
private String message;
private Item(boolean done) {
this.done = done;
}
private Item(String message) {
this.message = message;
}
public boolean isDone() {
return done;
}
public String getMessage() {
return message;
}
}
private class Producer implements Callable<Long> {
private final int id;
private Integer numOfMessages;
private Producer(int id, int numOfMessages) {
this.id = id;
this.numOfMessages = numOfMessages;
}
#Override
public Long call() throws Exception {
long totalTime = 0;
while (numOfMessages > 0) {
String message;
synchronized (numOfMessages) {
long starttime = System.nanoTime();
int msgLength = randGenerator.nextInt(20000);
StringBuilder sb = new StringBuilder(msgLength);
for (int a = 0; a < msgLength; a++) {
sb.append((char) ('a' + randGenerator.nextInt(26)));
}
message = sb.toString();
long endtime = System.nanoTime();
totalTime += endtime - starttime;
}
numOfMessages--;
queue.put(new Item(message));
}
System.out.println("-------------Producer " + id + " is done.");
queue.put(new Item(true));
return totalTime;
}
}
private class Consumer implements Callable<Long> {
private String monitor = "monitor";
private final int id;
private Consumer(int id) {
this.id = id;
}
#Override
public Long call() throws Exception {
long totalTime = 0;
while (true) {
Item item = queue.take();
if (item.isDone()) {
break;
}
synchronized (monitor) {
long starttime = System.nanoTime();
StringBuilder sb = new StringBuilder(item.getMessage());
sb = sb.reverse();
String message = sb.toString();
long endtime = System.nanoTime();
totalTime += endtime - starttime;
}
}
System.out.println("+++++++++++++Consumer " + id + " is done.");
return totalTime;
}
}
public void begin(int threadCount) throws InterruptedException, ExecutionException {
Collection<Producer> producers = new ArrayList<Producer>();
for (int i = 0; i < threadCount; i++) {
producers.add(new Producer(i, randGenerator.nextInt(5)));
}
Collection<Consumer> consumers = new ArrayList<Consumer>();
for (int i = 0; i < threadCount; i++) {
consumers.add(new Consumer(i));
}
try {
long starttime = System.nanoTime();
List<Future<Long>> producerFutureList = executorPool.invokeAll(producers);
List<Future<Long>> consumerFutureList = executorPool.invokeAll(consumers);
long producerTotalTime = 0;
long consumerTotalTime = 0;
for (Future<Long> future : producerFutureList) {
producerTotalTime += future.get();
}
for (Future<Long> future : consumerFutureList) {
consumerTotalTime += future.get();
}
long mainThreadTotalTime = System.nanoTime() - starttime;
System.out.println("producerTotalTime " + producerTotalTime);
System.out.println("consumerTotalTime " + consumerTotalTime);
System.out.println("mainThreadTotalTime " + mainThreadTotalTime);
System.out.println("Difference " + (producerTotalTime + consumerTotalTime - mainThreadTotalTime));
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw e;
} catch (ExecutionException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw e;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ProducersConsumers prodcon = new ProducersConsumers();
prodcon.begin(20);
}
}
You should close the ExecutorService when you are done with it. Call executorPool.shutdown() at the end of your program.
You seem to be using a shared resource, specifically numOfMessages outside of a synchronized block.
while (numOfMessages > 0) {
// blah
synchronized (numOfMessages) {
// blah
}
}
I don't think this is the cause of your problem, but it's certainly non thread-safe. It's a typical check-then-act scenario. Refer to either Java Concurrency in Practice or Effective Java for reasons why this is Not Good (TM).

How to access Hibernate session from src folder?

I would like to know how to access the Service and Domains properly in this sample class placed in src/java folder
public class NewsIngestion implements Runnable {
private String str;
private int num;
private Logger log = Logger.getLogger("grails.app");
private static boolean isRunning;
private Thread t;
private WorkerJobService jobService;
private NewsService newsService;
public NewsIngestion(String s, int n)
{
jobService = new WorkerJobService();
newsService = new NewsService();
str = s;
num = n;
isRunning = false;
t = new Thread (this, "NewsIngestion");
}
public void run ()
{
while(isRunning){
try{
if(jobService.isJobEnabled("ConsumeFeedsJob") && jobService.lockJob("ConsumeFeedsJob")){
log.info("${this.class.name}: ConsumeFeedsJob started");
try{
// get all sources
List sources = (List) InvokerHelper.invokeMethod(RSSFeed.class, "list", null);
for(int i = 0; i < sources.size(); i++) {
RSSFeed s = (RSSFeed) sources.get(i);
// check if it's time to read the source
int diff = DateTimeUtil.getSecondsDateDiff(s.getLastChecked(), new Date());
if(s.getLastChecked() == null || diff >= s.getCheckInterval()){
List keyword_list = (List) InvokerHelper.invokeMethod(Keyword.class, "list", null);
for(int j = 0; j < keyword_list.size(); j++) {
String keyword = (String) keyword_list.get(j);
try{
newsService.ingestNewsFromSources(keyword, s);
}catch(Exception e){
log.error("${this.class.name}: ${e}");
}
log.debug("Completed reading feeds for ${keyword}.");
log.info("${this.class.name}: Reading feeds for '${keyword}' (${s.feedName}) took ${Float.toString(st2.getDuration())} second(s).");
}
s.setLastChecked(new Date());
InvokerHelper.invokeMethod(RSSFeed.class, "save", null);
}
log.info("${this.class.name}: Reading feeds for '${s.feedName}' for all keywords took ${Float.toString(st.getDuration())} second(s).");
}
}catch(Exception e){
log.error("${this.class.name}: Exception: ${e}");
}
log.info("${this.class.name}: ConsumeFeedsJob ended.");
// unlock job
jobService.unlockJob("ConsumeFeedsJob");
}
log.info("alfred: success");
}
catch (Exception e){
log.info("alfred exception: " + e.getMessage());
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
log.info(e.getMessage());
}
}
}
public void start() {
if(t == null){
t = new Thread (this, "NewsIngestion");
}
if(!isRunning){
isRunning = true;
t.start();
}
}
public void stop() {
isRunning = false;
}
public boolean isRunning() {
return isRunning;
}
}
I'm encountering this error message:
No Hibernate Session bound to thread,
and configuration does not allow
creation of non-transactional one here
Thanks.
You shouldn't instantiate the service class by yourself, but instead take the class instance from the main context
import org.codehaus.groovy.grails.commons.ApplicationHolder
def ctx = ApplicationHolder.application.mainContext
def newsService = ctx.newsService
If you're using Java
import org.codehaus.groovy.grails.commons.ApplicationHolder
public class SomeClass {
SomeService someService;
public SomeClass() {
someService = (SomeService) ApplicationHolder.getApplication().getMainContext().getBean("someService");
}
}
Consider using Spring and #Transactional annotation or AOP.

Categories