java - How to process failed Futures -
i'm integrating legacy library have no control of.
it has following interface defined:
interface factory { future<void> subscribe(context c); }
this "subscribe" method called , different threads. situation when care result of "future.get()" when fails, can , process exception. doesn't have happen in calling thread. plus, blocking calling thread on "future.get()" can quite expensive in case, cause may take seconds fullfill if successfull.
so task somehow "post process" these futures, filtering failed ones. basically, can see 2 possible approaches:
approach #1:
on obtaining instance of future, submit separate runnable external executor required:
executor.submit( new runnable(){ @override public void run() { try { future.get(); } catch(exception e){ // process exception } } } );
the drawback of approach still blocking thread potentially long time period. , said, code snippet executed rather frequently.
approach #2:
on obtaining instance of future, place collection , dedicate separate single thread periodically run through elements of collection doing processing:
while(true){ iterator<future<void>> iterator = collection.iterator(); while(iterator.hasnext()){ future<void> future = iterator.next(); if(future.isdone()){ try { future.get(); } catch(exception e){ // process exception } { iterator.remove(); } } } timeunit.milliseconds.sleep(1000); // sleep }
what think? there better way of solving problem?
since have no hands on creation of future
best option not available, trigger processing future
using customized future
.
so in case recommend pattern might mixture of 2 options. add future
s (thread-safe) queue , submit runnable
s executor process items in loop. can limit number of threads configuring executor
, i.e. don’t have threads future
s still can have more 1 , don’t have keep these post-processing threads alive time.
in order avoid infinite loop when re-queue unfinished items, use local collection separate pending re-queued items:
static blockingqueue<future<?>> pending = …; static int max_items_per_job = …; … /*scheduling code …*/new runnable() { public void run() { arraylist<future<?>> mylocalitems=new arraylist<>(); pending.drainto(mylocalitems, max_items_per_job); for(future<?> f:mylocalitems) { if(!f.isdone()) pending.offer(f); // re-queue try { f.get(); } catch(executionexception ex) { handleexception(ex.getcause()); } } } };
so runnable
check , process limited number of future
s , return it’s suitable submitted multiple times parallel processing if lot of items pending no harm if lesser number pending jobs not hang around if there’s nothing do. suitable schedulewithfixeddelay
using scheduledexecutorservice
.
Comments
Post a Comment