/** * Build the {@link EventProcessor}. * * @return built Event processor instance. */ public EventProcessor build() { return new EventProcessor(this); } }
private void notify(final Collection<EventListener> listeners, final InboundEvent event) { for (EventListener listener : listeners) { notify(listener, event); } }
try { try { final Invocation.Builder request = prepareHandshakeRequest(); if (state.get() == State.OPEN) { // attempt to connect only if even source is open LOGGER.debugLog("Connecting..."); if (eventInput == null || eventInput.isClosed()) { LOGGER.debugLog("Connection lost - scheduling reconnect in {0} ms", reconnectDelay); scheduleReconnect(reconnectDelay); break; } else { this.onEvent(eventInput.read()); scheduleReconnect(delay); } catch (Exception ex) { if (LOGGER.isLoggable(CONNECTION_ERROR_LEVEL)) {
@Override public void open() { if (!state.compareAndSet(EventProcessor.State.READY, EventProcessor.State.OPEN)) { switch (state.get()) { case CLOSED: throw new IllegalStateException(LocalizationMessages.EVENT_SOURCE_ALREADY_CLOSED()); case OPEN: throw new IllegalStateException(LocalizationMessages.EVENT_SOURCE_ALREADY_CONNECTED()); } } EventProcessor processor = EventProcessor .builder(endpoint, state, clientExecutor, this::onEvent, this::close) .reconnectDelay(reconnectDelay, reconnectTimeUnit) .build(); clientExecutor.submit(processor); // return only after the first request to the SSE endpoint has been made processor.awaitFirstContact(); }
/** * Open the connection to the supplied SSE underlying {@link WebTarget web target} and start processing incoming * {@link InboundEvent events}. * * @throws IllegalStateException in case the event source has already been opened earlier. */ public void open() { if (!state.compareAndSet(EventProcessor.State.READY, EventProcessor.State.OPEN)) { switch (state.get()) { case OPEN: throw new IllegalStateException(LocalizationMessages.EVENT_SOURCE_ALREADY_CONNECTED()); case CLOSED: throw new IllegalStateException(LocalizationMessages.EVENT_SOURCE_ALREADY_CLOSED()); } } EventProcessor.Builder builder = EventProcessor.builder(target, state, executor, this, shutdownHandler) .boundListeners(boundListeners) .unboundListeners(unboundListeners) .reconnectDelay(reconnectDelay, TimeUnit.MILLISECONDS); if (disableKeepAlive) { builder.disableKeepAlive(); } EventProcessor processor = builder.build(); executor.submit(processor); // return only after the first request to the SSE endpoint has been made processor.awaitFirstContact(); }
/** * Called by the event source when an inbound event is received. * * This listener aggregator method is responsible for invoking {@link EventSource#onEvent(InboundEvent)} * method on the owning event source as well as for notifying all registered {@link EventListener event listeners}. * * @param event incoming {@link InboundEvent inbound event}. */ @Override public void onEvent(final InboundEvent event) { if (event == null) { return; } LOGGER.debugLog("New event received."); if (event.getId() != null) { lastEventId = event.getId(); } if (event.isReconnectDelaySet()) { reconnectDelay = event.getReconnectDelay(); } notify(eventListener, event); notify(unboundListeners, event); final String eventName = event.getName(); if (eventName != null) { final List<EventListener> eventListeners = boundListeners.get(eventName); if (eventListeners != null) { notify(eventListeners, event); } } }
/** * Schedule a new event processor task to reconnect after the specified {@code delay} [milliseconds]. * * If the {@code delay} is zero or negative, the new reconnect task will be scheduled immediately. * The {@code reconnectDelay} and {@code lastEventId} field values are propagated into the newly * scheduled task. * <p> * The method will silently abort in case the event source is not {@link EventSource#isOpen() open}. * </p> * * @param delay specifies the amount of time [milliseconds] to wait before attempting a reconnect. * If zero or negative, the new reconnect task will be scheduled immediately. */ private void scheduleReconnect(final long delay) { final State s = state.get(); if (s != State.OPEN) { LOGGER.debugLog("Aborting reconnect of event source in {0} state", state); return; } // propagate the current reconnectDelay, but schedule based on the delay parameter final EventProcessor processor = new EventProcessor(this); if (delay > 0) { executor.schedule(processor, delay, TimeUnit.MILLISECONDS); } else { executor.submit(processor); } }