hudi
hudi

Reputation: 16555

How to create pool of clients which can handle just one task at once

My application starts couple of clients which communicate with steam. There are two types of task which I can ask for clients. One when I don't care about blocking for example ask client about your friends. But second there are tasks which I can submit just one to client and I need to wait when he finished it asynchronously. So I am not sure if there is already some design pattern but you can see what I already tried. When I ask for second task I removed it from queue and return it here after this task is done. But I don't know if this is good sollution because I can 'lost' some clients when I do something wrong

@Component
public class SteamClientWrapper {

private Queue<DotaClientImpl> clients = new LinkedList<>();

private final Object clientLock = new Object();

public SteamClientWrapper() {
}

@PostConstruct
public void init() {
    // starting clients here   clients.add();     
}

public DotaClientImpl getClient() {
    return getClient(false);
}

public DotaClientImpl getClient(boolean freeLast) {
    synchronized (clients) {
        if (!clients.isEmpty()) {
            return freeLast ? clients.poll() : clients.peek();
        }
    }

    return null;
}

public void postClient(DotaClientImpl client) {
    if (client == null) {
        return;
    }

    synchronized (clientLock) {
        clients.offer(client);
        clientLock.notify();
    }
}

public void doSomethingBlocking() {
    DotaClientImpl client = getClient(true);
    client.doSomething();
}

}

Upvotes: 1

Views: 44

Answers (1)

Roland Kreuzer
Roland Kreuzer

Reputation: 992

Sounds like you could use Spring's ThreadPoolTaskExecutor to do that.

An Executor is basically what you tried to do - store tasks in a queue and process the next as soon the previous has finished. Often this is used to run tasks in parallel, but it can also reduce overhead for serial processing.

A sample doing it this way would be on https://dzone.com/articles/spring-and-threads-taskexecutor

To ensure only one client task runs at a time, simply set the configuration to

    executor.setCorePoolSize(1);
    executor.setMaxPoolSize(1);

Upvotes: 0

Related Questions