Сервер отправил события с помощью sseemitter, и на ответ требуется больше времени

У меня есть требование отправлять уведомление из базы данных SQL пользователю, поскольку сервер отправляет события в Spring Boot. Я использовал SseEmitter для реализации этого.

1) @GetMapping(value = "/v2/user/notifications/event",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public ResponseEntity<SseEmitter> sendNotification(@RequestHeader(value = "Authorization") final String token) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("Connection","keep-alive");
        headers.add("Cache-Control", "no-cache");
        List<HttpStatus> httpStatuses = new ArrayList<>();
        httpStatuses.add(0, HttpStatus.OK);


        SseEmitter sseEmitter = new SseEmitter(Long.MAX_VALUE);
        Integer nextEventFireTime = appConfig.getConfiguration().getInteger("sse.nextEventFireTime");

        ScheduledExecutorService scheduledExecutorService =
                Executors.newScheduledThreadPool(Constants.MAX_THREAD_POOL_SSE);

        scheduledExecutorService.scheduleAtFixedRate(() -> {
            try {
                service.sendNotification(sseEmitter, token);
            } catch (BaseException e) {
                httpStatuses.add(0, HttpStatus.INTERNAL_SERVER_ERROR);
                sseEmitter.completeWithError(e);
                scheduledExecutorService.shutdown();
            }
        } , 0, nextEventFireTime, TimeUnit.SECONDS);

        return new ResponseEntity<>(sseEmitter, headers, httpStatuses.get(0));
    }

* nextEventFireTime настроен как 15

2)@Override
    public synchronized void sendNotification(SseEmitter emitter, String token) throws BaseException {

        NotificationMetadata notificationMetadata =
                getUnreadNotificationCount(token);

        List<Notification2> notificationList;
        notificationList =
                getSseNotifications(token);

        SseEmitter.SseEventBuilder event = SseEmitter.event();

        NotificationResponse2 notificationResponse2 = new NotificationResponse2();
        notificationResponse2.setData(notificationList);
        notificationResponse2.setMetadata(notificationMetadata);

        event.name(Constants.SSE_EVENT_NAME).data(notificationResponse2)
                .build();
        try {
            emitter.send(event.reconnectTime(15000L));
        } catch (Exception e) {
            throw new BaseException("Failed to send notification event.. "+e.getMessage(), Constants.ERROR_CODE_INTERNAL_ERROR,
                    "sendNotification", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

Клиент ожидает ответа, и это занимает около 17 минут, когда в базе данных нет данных для уведомления, но запрос счетчика извлекает данные, а когда есть данные, то также требуется 4-5 минут, чтобы дать ответ.

Я использую SseEmitter в первый раз, и когда я отлаживаю код на сервере, выполняется, но ответ все еще ожидает ответа.

Может ли кто-нибудь помочь мне с этим вопросом?

Почему метод synchronized ? Кроме того, зачем воссоздавать ScheduledExecutorService, вам лучше настроить TaskScheduler и использовать его повторно (теперь вы рискуете создать множество потоков, которые могут действительно замедлить работу). Вы также дважды перестраиваете событие, не зная, зачем вы это делаете.

M. Deinum 20.11.2018 08:17

Я использовал synchronized, потому что есть 2 запроса для получения данных, и я хочу, чтобы один поток завершил выполнение до прерывания другого потока. Я не использую планировщик задач, потому что SSE должен передавать данные только тогда, когда одна регистрация выполняется от пользователя, и я создаю событие, а затем выполняю сборку в следующей строке.

Priyanka Mourya 25.11.2018 14:01

Результат вызова build игнорируется, следовательно, это событие 1 ... Затем вы вызываете reconnectTime, который создает другое событие, следовательно, вы создаете несколько событий. Кроме того, если вы хотите, чтобы он был однопоточным, тогда зачем вообще делать его асинхронным? Похоже, много работы без всякой выгоды.

M. Deinum 26.11.2018 08:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
978
0

Другие вопросы по теме