Should an open source library with a blocking method offer an asynchronous option for execution?

67 Views Asked by At

Background:

I am creating library that I want to make open source. This library is designed for use in backend processes. The service I will make available utilizes Java's ProcessBuilder, to execute several native commands. This service will often finish processing commands in under 1 second, but in rare cases, may take several minutes.

Questions:

In a situation where a public library has methods that may become blocking, should the library provide an async option for calling that method? Or should such a library remain unopinionated, and leave that to the users to implement?

Here are a couple ways of how I have been thinking of implementing this service...

Example 1: unopinionated

  • SomeService, with blocking method
  • if user wants to run asynchronously, they must figure it out

SomeService.java

public class SomeService {
    public Response process(Request request) {
        //do stuff for 60 seconds
    }
}

Example 2: opinionated

  • SomeService, with blocking method
  • optional SomeProcessTask, which users can utilize to bypass blocking method and run async.

SomeProcessTask.java

public class SomeProcessTask implements Callable<Response> {
    private final Request request;

    public SomeProcessTask(Request request) {
        this.request = request;
    }

    @Override
    public Response call(Request request) {
        //do stuff for 60 seconds
    }
}

SomeService.java

public class SomeService {
    public Response process(Request request) {
        SomeProcessTask task = new SomeProcessTask(request);
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Response> future = executor.submit(task);
        return future.get();
    }
}
1

There are 1 best solutions below

1
Basil Bourque On BEST ANSWER

You commented:

I am not very experienced with concurrency

Then you most definitely should not attempt making your library run concurrently. Concurrency is tricky. An example is the code seen in the Question; multiple concurrency problems have been identified in the Comments.

Keep your library simple. Focus on its core purpose. Let the calling programmer deal with concurrency if they deem it important.

You should document for the calling programmer any aspects of your library that may impact its use concurrently. Most especially, mention any issue that would contraindicate its use with virtual threads. Such issues include:

  • Calling out to native code.
  • Running long-executing work within synchronized blocks. (Or else re-implement those with ReentrantLock.)
  • Being CPU-bound for long-executing work. For example, video-encoding without any blocking calls like logging, file I/O, database interaction, or network access.

To learn more about concurrency, read the book Java Concurrency in Practice by Brian Goetz et al. And study the Java Memory Model.

To learn about virtual threads, see talks by Ron Pressler, Alan Bateman, or José Paumard.