Как вызвать отключение Guava AbstractScheduledService? - PullRequest
0 голосов
/ 30 сентября 2018

Я использую несколько сервисов, унаследованных от AbstractScheduledService, которыми управляет ServiceManager.Все работает нормально, но теперь есть служба, для которой runOneIteration занимает довольно много времени, и в результате мой процесс завершается слишком долго (более пяти секунд).

Существуют другие службы, наследующиеиз AbstractExecutionThreadService, в которой была похожая проблема, которую я мог решить с помощью

@Override
protected final void triggerShutdown() {
    if (thread != null) thread.interrupt();
}

и сохранением private volatile thread в методе run.Однако triggerShutdown для AbstractScheduledService, как указано в этой проблеме .

, я уже рассматривал альтернативы, такие как runOneIteration, выполняющий меньше работы, но он уродлив и неэффективен.

Я не могу переопределить stopAsync, так как он окончательный и больше ничего не вижу. Есть ли ловушка для того, чтобы делать что-то подобное?

1 Ответ

0 голосов
/ 09 октября 2018

Вы можете работать с этим?Была ли какая-то причина, по которой вы не смогли добавить триггер-выключение самостоятельно?

class GuavaServer {
    public static void main(String[] args) throws InterruptedException {
        GuavaServer gs = new GuavaServer();
        Set<ForceStoppableScheduledService> services = new HashSet<>();
        ForceStoppableScheduledService ts = gs.new ForceStoppableScheduledService();
        services.add(ts);
        ServiceManager manager = new ServiceManager(services);
        manager.addListener(new Listener() {
            public void stopped() {
                System.out.println("Stopped");
            }

            public void healthy() {
                System.out.println("Health");
            }

            public void failure(Service service) {
                System.out.println("Failure");
                System.exit(1);
            }
        }, MoreExecutors.directExecutor());

        manager.startAsync(); // start all the services asynchronously
        Thread.sleep(3000);
        manager.stopAsync();
        //maybe make a manager.StopNOW()?
        for (ForceStoppableScheduledService service : services) {
            service.triggerShutdown();
        }
    }

    public class ForceStoppableScheduledService extends AbstractScheduledService {

        Thread thread;

        @Override
        protected void runOneIteration() throws Exception {
            thread = Thread.currentThread();
            try {
                System.out.println("Working");
                Thread.sleep(10000);
            } catch (InterruptedException e) {// can your long process throw InterruptedException?
                System.out.println("Thread was interrupted, Failed to complete operation");
            } finally {
                thread = null;
            }
            System.out.println("Done");
        }

        @Override
        protected Scheduler scheduler() {
            return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
        }

        protected void triggerShutdown() {
            if (thread != null) thread.interrupt();
        }
    }
}
...