Axon-始终重新投影所有事件

时间:2019-03-12 14:09:40

标签: java axon

是否可以使用usingSubscribingEventProcessors,并且在投影事件时,请始终从头开始重新投影所有事件。含义-我从不将投影保存到数据库,而是在Aggregate发出新事件时重新投影所有事件?

2 个答案:

答案 0 :(得分:1)

当然可以! 但是,您无法通过使用“订阅事件处理器”来实现。 您应该利用跟踪事件处理器,但后面要有InMemoryTokenStore。这样做,应用程序就永远无法从停止的地方开始,因为TrackingToken并不存在。

因此,最终每次启动时都会重新创建投影。

您可以采用的另一种方法有些不同。 您仍将使用跟踪事件处理器,但使用实际的持久性TokenStore实现。其次,在应用程序启动时,您可以使用TrackingEventProcessor#resetTokens()函数来重播给定的跟踪事件处理器。

采用这种方法,您可以在事件处理组件中添加带有注释的@ResetHandler函数,以清除投影表之前,以便再次处理所有事件。

希望这会给您Bojan一些见解!

答案 1 :(得分:0)

@Steven,您对此解决方案有何看法?

public class ReplayingSubscribingEventProcessor extends SubscribingEventProcessor {

  private final SubscribableMessageSource<? extends EventMessage<?>> messageSource;

  protected ReplayingSubscribingEventProcessor(
      Builder builder) {
    super(builder);
    this.messageSource = builder.messageSource;
  }

  public static Builder builder() {
    return new Builder();
  }

  /**
   * Whenever there is a need to process event messages, ignore all of them and since already inside messageSource,
   * just take all messages from event source and re-project all from beginning for this aggregate root
   * @param eventMessages
   */
  @Override
  protected void process(List<? extends EventMessage<?>> eventMessages) {
    try {
      //reprocess all previous events for this aggregate (get id from current event)
      GenericDomainEventMessage gdem = (GenericDomainEventMessage) eventMessages.get(0);
      List<? extends EventMessage<?>> prevEvs = ((EventStore)messageSource).readEvents(gdem.getAggregateIdentifier()).asStream()
          .collect(Collectors.toList());
      processInUnitOfWork(prevEvs, new BatchingUnitOfWork<>(prevEvs), Segment.ROOT_SEGMENT);
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new EventProcessingException("Exception occurred while processing events", e);
    }
  }

  public static class Builder extends SubscribingEventProcessor.Builder{
    private SubscribableMessageSource<? extends EventMessage<?>> messageSource;

    @Override
    public Builder messageSource(
        SubscribableMessageSource<? extends EventMessage<?>> messageSource) {
      super.messageSource(messageSource);
      this.messageSource = messageSource;
      return this;
    }

    @Override
    public ReplayingSubscribingEventProcessor.Builder name(String name) {
      super.name(name);
      return this;
    }

    @Override
    public ReplayingSubscribingEventProcessor.Builder eventHandlerInvoker(
        EventHandlerInvoker eventHandlerInvoker) {
      super.eventHandlerInvoker(eventHandlerInvoker);
      return this;
    }

    @Override
    public ReplayingSubscribingEventProcessor.Builder processingStrategy(
        EventProcessingStrategy processingStrategy) {
      super.processingStrategy(processingStrategy);
      return this;
    }

    public ReplayingSubscribingEventProcessor build() {
      return new ReplayingSubscribingEventProcessor(this);
    }
  }
}

和配置:

@Autowired
    public void configure(EventProcessingConfigurer configurer){
        configurer.registerEventProcessor("inMemoryProcessor",
                (n, c, ehi) -> replayingSubscribingEventProcessor(n, c, ehi, org.axonframework.config.Configuration::eventBus));
    }

    public ReplayingSubscribingEventProcessor replayingSubscribingEventProcessor(
            String name,
            org.axonframework.config.Configuration conf,
            EventHandlerInvoker eventHandlerInvoker,
            Function<org.axonframework.config.Configuration, SubscribableMessageSource<? extends EventMessage<?>>> messageSource) {
        return ReplayingSubscribingEventProcessor.builder()
                .name(name)
                .eventHandlerInvoker(eventHandlerInvoker)
                .messageSource(messageSource.apply(conf))
                .processingStrategy(DirectEventProcessingStrategy.INSTANCE)
                .build();
    }