Как создать пул клиентов, который может обрабатывать только одну задачу одновременно - PullRequest
1 голос
/ 01 марта 2020

Мое приложение запускает пару клиентов, которые общаются со steam. Есть два типа задач, которые я могу задать клиентам. Например, когда меня не интересует блокировка, спрашивай клиента о своих друзьях. Но во-вторых, есть задачи, которые я могу отправить только одному клиенту, и мне нужно подождать, когда он завершит его асинхронно. Поэтому я не уверен, есть ли уже какой-то шаблон проектирования, но вы можете увидеть, что я уже пробовал. Когда я запрашиваю второе задание, я удаляю его из очереди и возвращаю сюда после выполнения этого задания. Но я не знаю, является ли это хорошим решением, потому что я могу «потерять» некоторых клиентов, когда я делаю что-то не так

@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();
}

}

1 Ответ

0 голосов
/ 01 марта 2020

Звучит так, как будто вы можете использовать SpringPoolTaskExecutor для этого.

Executor - это то, что вы пытались делать - сохранять задачи в очереди и обрабатывать последующие, как только завершится предыдущая. Часто это используется для параллельного выполнения задач, но это также может снизить накладные расходы на последовательную обработку.

Пример, выполняющий этот способ, будет https://dzone.com/articles/spring-and-threads-taskexecutor

Чтобы гарантировать, что одновременно выполняется только одна клиентская задача, просто установите конфигурацию на

    executor.setCorePoolSize(1);
    executor.setMaxPoolSize(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...