2
\$\begingroup\$

I need to refactor this class having in mind that the logic inside the call methods is not so short and it require spring dependencies to work, the base class I have is:

@Service
public class ConcurrentService{

    @Autowired
    private Service1 service1;

    @Autowired
    private Service2 service2;

    public executeParallelProcess(){
        List<Callable> callableList = new ArrayList<Callable>();
        callableList.add(new Callable<String>(){

            @Override 
            public String call() throws Exception {
                return service1.run();
            }
        });

        callableList.add(new Callable<String>(){

            @Override 
            public String call() throws Exception {
                return service2.run();
            }
        });


        final List<Future<?>> futureList = new ArrayList<Future<?>>();

        for(Callable callable : callableList){
            futureList.add(taskExecutor.submit(callable));
        }

        final List<Object> resultObjects = new ArrayList<Object>();

        for(int i = 0 ; i < futureList.size() ; i++){
            try {
                resultObjects.add(futureList.get(i).get());
            }catch (InterruptedException ite){
                serviceExceptionThrown = true;
            }
        }

        if(serviceExceptionThrown)
            throw new ServiceException(ConstantUtil.THREAD_EXCEPTION);

        return resultObjects;

    }
}

After notice that I can not use Mockito to test the logic within the call method I use this way.

@Service
public class ConcurrentService{

    @Autowired
    private Service1 service1;

    @Autowired
    private Service2 service2;


    public executeParallelProcess(){

        Future<String> future1 = this.process1();
        Future<String> future2 = this.process2();

        final List<Future<?>> futureList = new ArrayList<Future<?>>();
        futureList.add(cosmosRequestCall);
        futureList.add(vendavoRequestCall);

        final List<Object> resultObjects = new ArrayList<Object>();

        for(int i = 0 ; i < futureList.size() ; i++){
            try {
                resultObjects.add(futureList.get(i).get());
            }catch (InterruptedException ite){
                serviceExceptionThrown = true;
            }
        }

        if(serviceExceptionThrown)
            throw new ServiceException(ConstantUtil.THREAD_EXCEPTION);

        return resultObjects;

    }


    @Async
    public Future<String> process1(){
        return new AsyncResult<String>(service1.run());
    }

    @Async
    public Future<String> process2(){
        return new AsyncResult<String>(service2.run());
    }
}

I need your advise and help here, to know if there is better way to implement this kind of logic, have in mind that could be more than 2 async processes , I am looking for a generic way to run several callable statements in a way that makes me easy the unit testing of the internal process and not having big blocks of code within the call() method.

The question is more about how to design an executor class that can run several callable in different scenarios for different situation not just tied to an specific implementation. I use anonymous classes, inner classes to create. Just imagine something that I can built to run more than the two thread process that are in the example.

\$\endgroup\$
3
\$\begingroup\$

To test these things the first thing I usually do is wire in a sameThreadExecutor; if you don't want a dependency you'll have to write your own but it's just an implementation of ExecutorService that calls its callable immediately and returns a completed future.

The aim is to replace the async part of your code with something synchronous. The mocking could be done with Mockito, it's just very unwieldy. You would have to mock the task executor with a doAnswer:

Mockito.when(taskExecutor.call(any())).thenAnswer((invocation) -> ... ugly work goes here ...)

For safety you might want to add timeout parameters to the call() method and handle timeout exceptions (cancel the timed out future).

\$\endgroup\$
  • \$\begingroup\$ thanks for you answer but I just want to know a little bit about the design of the executor class, imagine this scenario, have several process that need to run in parallel what should be the best structure or design for the class that execute the callable anonymous classes. use anonymous Callable classes, use inner classes or use @async with methods, any strategy you suggest ? \$\endgroup\$ – Koitoer Jun 19 '15 at 4:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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