/** * Handles a publish request. * * @param request The publish request to handle. * @return A completable future to be completed with the publish response. */ @SuppressWarnings("unchecked") private CompletableFuture<PublishResponse> handlePublish(PublishRequest request) { if (request.session() != id) return Futures.exceptionalFuture(new UnknownSessionException("incorrect session ID")); if (request.previousVersion() != eventVersion) { return CompletableFuture.completedFuture( PublishResponse.builder() .withStatus(Response.Status.ERROR) .withError(RaftError.Type.INTERNAL_ERROR) .withVersion(eventVersion) .build()); } eventVersion = request.eventVersion(); List<CompletableFuture<Void>> futures = new ArrayList<>(request.events().size()); for (Event<?> event : request.events()) { Listeners<Object> listeners = eventListeners.get(event.name()); if (listeners != null) { futures.add(listeners.accept(event.message())); } } return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[futures.size()])) .handleAsync( (result, error) -> { completeVersion = Math.max(completeVersion, request.eventVersion()); return PublishResponse.builder() .withStatus(Response.Status.OK) .withVersion(eventVersion) .build(); }, context.executor()); }
@Override @SuppressWarnings("unchecked") public synchronized Listener onEvent(String event, Consumer listener) { Listeners listeners = eventListeners.get(event); if (listeners == null) { listeners = new Listeners(); eventListeners.put(event, listeners); parent.onEvent(event, message -> handleEvent(event, (InstanceEvent) message)); } return listeners.add(listener); }
@Override public Session publish(String event, Object message) { Assert.notNull(event, "event"); context .executor() .execute( () -> { Listeners<Object> listeners = eventListeners.get(event); if (listeners != null) { listeners.accept(message); } }); return this; }
/** Handles expiring the session. */ private void onExpire() { if (isOpen()) { LOGGER.debug("Expired session: {}", id); this.id = 0; this.state = State.EXPIRED; closeListeners.forEach(l -> l.accept(this)); } }
/** Handles closing the session. */ private void onClose() { if (isOpen()) { LOGGER.debug("Closed session: {}", id); this.id = 0; this.state = State.CLOSED; if (connection != null) connection.close(); client.close(); context.close(); closeListeners.forEach(l -> l.accept(this)); } }
@Override public Listener<Session> onClose(Consumer<Session> listener) { return closeListeners.add(Assert.notNull(listener, "listener")); }
@Override public Listener<Session> onOpen(Consumer<Session> listener) { return openListeners.add(Assert.notNull(listener, "listener")); }