private StructuredLogger structuredLogger(Event event, MailboxListener mailboxListener) { return MDCStructuredLogger.forLogger(LOGGER) .addField(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId()) .addField(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass()) .addField(EventBus.StructuredLoggingFields.USER, event.getUser()) .addField(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass()); } }
@Override public Mono<Void> dispatch(Event event, Set<RegistrationKey> keys) { if (!event.isNoop()) { return Flux.merge(groupDeliveries(event), keyDeliveries(event, keys)) .reduceWith(EventDelivery.ExecutionStages::empty, EventDelivery.ExecutionStages::combine) .flatMap(EventDelivery.ExecutionStages::synchronousListenerFuture) .then() .onErrorResume(throwable -> Mono.empty()); } return Mono.empty(); }
@Override public Mono<Event> failedEvent(Group registeredGroup, Event.EventId failDeliveredEventId) { Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL); Preconditions.checkArgument(failDeliveredEventId != null, FAIL_DELIVERED_ID_EVENT_CANNOT_BE_NULL); return Flux.fromIterable(deadLetters.get(registeredGroup)) .filter(event -> event.getEventId().equals(failDeliveredEventId)) .next(); }
@Override public Mono<Void> remove(Group registeredGroup, Event.EventId failDeliveredEventId) { Preconditions.checkArgument(registeredGroup != null, REGISTERED_GROUP_CANNOT_BE_NULL); Preconditions.checkArgument(failDeliveredEventId != null, FAIL_DELIVERED_ID_EVENT_CANNOT_BE_NULL); return Flux.fromIterable(deadLetters.get(registeredGroup)) .filter(event -> event.getEventId().equals(failDeliveredEventId)) .next() .doOnNext(event -> deadLetters.remove(registeredGroup, event)) .subscribeWith(MonoProcessor.create()) .then(); }
private void doDeliverToListener(MailboxListener mailboxListener, Event event) { TimeMetric timer = metricFactory.timer(timerName(mailboxListener)); try (Closeable mdc = MDCBuilder.create() .addContext(EventBus.StructuredLoggingFields.EVENT_ID, event.getEventId()) .addContext(EventBus.StructuredLoggingFields.EVENT_CLASS, event.getClass()) .addContext(EventBus.StructuredLoggingFields.USER, event.getUser()) .addContext(EventBus.StructuredLoggingFields.LISTENER_CLASS, mailboxListener.getClass()) .build()) { mailboxListener.event(event); } catch (Exception e) { throw new RuntimeException(e); } finally { timer.stopAndPublish(); } }
@Test default void retryingListenerCallingDispatchShouldNotFail() { AtomicBoolean firstExecution = new AtomicBoolean(true); AtomicBoolean successfulRetry = new AtomicBoolean(false); MailboxListener listener = event -> { if (event.getEventId().equals(EVENT_ID)) { if (firstExecution.get()) { firstExecution.set(false); throw new RuntimeException(); } eventBus().dispatch(EVENT_2, NO_KEYS).block(); successfulRetry.set(true); } }; eventBus().register(listener, GROUP_A); eventBus().dispatch(EVENT, NO_KEYS).block(); WAIT_CONDITION.until(successfulRetry::get); }
@Test default void listenersShouldBeAbleToDispatch() { AtomicBoolean successfulRetry = new AtomicBoolean(false); MailboxListener listener = event -> { if (event.getEventId().equals(EVENT_ID)) { eventBus().dispatch(EVENT_2, NO_KEYS).block(); successfulRetry.set(true); } }; eventBus().register(listener, GROUP_A); eventBus().dispatch(EVENT, NO_KEYS).block(); WAIT_CONDITION.until(successfulRetry::get); }