Ресурс Джерси @PreDestroy не вызывается, когда сервер Grizzley выключен - PullRequest
0 голосов
/ 30 октября 2018

Я использую простой HTTP-сервер Джерси / Гризли с ресурсом для обработки отправленных сервером событий .

Этот ресурс должен вручную позаботиться об экземпляре Timer, чтобы отправить некоторые данные поддержки активности всем подключенным клиентам SSE, поэтому я использую аннотации @PostConstruct и @PreDestroy для создания и отмены этого таймера (и его фона). нить).

Приложение представляет собой простое консольное приложение, не встроенное ни в одну контейнерную среду, например Tomcat. После запуска веб-сервера он ожидает простой System.in.read() и снова выключает сервер, вызывая shutdownNow () на экземпляре сервера Grizzly HTTP.

При подключении к ресурсу SSE создается экземпляр класса ресурса и запускается таймер. После отключения от сервера, после небольшой задержки ресурс снова уничтожается и все в порядке.

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

Если я сейчас попытаюсь выключить сервер, вызвав shutdownNow(), пока клиент подключен, экземпляр сервера корректно завершает работу, но не вызывает никаких методов @PreDestroy активных ресурсов. Это приводит к тому, что мой ресурс с экземпляром Timer остается на месте, и поскольку таймер все еще активен, это, в свою очередь, поддерживает выполнение процесса Java, даже если сервер HTTP уже выключен.

Есть ли способ получить все активные в данный момент экземпляры ресурса, чтобы я мог вручную вызвать их соответствующий метод уничтожения перед выключением HTTP-сервера? Или это может быть ошибка в управлении экземпляром ресурса сервер Гризли?

Используются следующие версии:

  • jersey-container-grizzly2-http: 2.27
  • grizzly-http-server: 2.4.0 (зависимость сверху)

Это версия кода с кодом:

public class ServerSentEventResource {
    @Context
    private Sse sse;
    private volatile SseBroadcaster broadcaster;
    private final Timer timer = new Timer();

    @PostConstruct
    public void init() {
        broadcaster = sse.newBroadcaster();
        final TimerTask task = new TimerTask() {
            // ...
        };
        timer.scheduleAtFixedRate(task, 0, 1000);
    }

    @PreDestroy
    public void destroy() {
        timer.cancel();
        broadcaster.close();
    }

    @GET
    @Produces(SseFeature.SERVER_SENT_EVENTS)
    public void get(@Context final SseEventSink eventSink) {
        broadcaster.register(eventSink);
    }
}

public static void main(final String[] args) {
    ResourceConfig resourceConfig = new ResourceConfig();
    resourceConfig.register(ServerSentEventResource.class);

    HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create("0.0.0.0:8888"), resourceConfig);
    System.in.read();
    server.shutdownNow();

    // At this point there is still the resource instance around, keeping the timer running, thus keeping the JVM running :(
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...