spring-modulith icon indicating copy to clipboard operation
spring-modulith copied to clipboard

spring-modulith: spring.modulith.republish-outstanding-events-on-restart=true unable

Open PetricHwang opened this issue 1 year ago • 4 comments
trafficstars

I set spring.modulith.republish-outstanding-events-on-restart=true, @ApplicationModuleListener sleep 30s, and I restart springboot, but it is unable republish.

  • publisher
ApplicationEventPublisher applicationEventPublisher;
...
List<AdminCreateEvent> events=...;
applicationEventPublisher.publishEvent(new ListenerEvent<>(this, events));

  • listener
@ApplicationModuleListener
public void listener(ListenerEvent<List<AdminCreateEvent>> event)  {
    log.debug("listener: {}", event);
    Thread.sleep(30_000)
}
  • ListenerEvent
import lombok.Getter;
import org.springframework.context.ApplicationEvent;

@Getter
public class ListenerEvent<T> extends ApplicationEvent {

    private final transient T data;

    public ListenerEvent(Object source, T data) {
        super(source);
        this.data = data;
    }
}
  • mysql record:
ID LISTENER_ID EVENT_TYPE SERIALIZED_EVENT PUBLICATION_DATE COMPLETION_DATE
6a969ce-5aa8-43ce-bcce-5da833fbe981 com.admin.event.AdminEventListener.listener(com.admin.event.ListenerEvent) com.admin.event.ListenerEvent {"timestamp":1710505254886,"data":[{"eventId":"c883e482-013a-4237-bdec-d6c1f0d7f403"}],"source":{}} 2024-03-15 20:20:54.887171

PetricHwang avatar Mar 15 '24 13:03 PetricHwang

It's not clear what “unable to republish” means. Would you mind creating a minimal reproducer to show what's going wrong?

odrotbohm avatar Mar 17 '24 15:03 odrotbohm

It's not clear what “unable to republish” means. Would you mind creating a minimal reproducer to show what's going wrong?

Unconsumed records(ID:6a969ce-5aa8-43ce-bcce-5da833fbe981) cannot be consumed after springboot restarts.

@ApplicationModuleListener
public void listener(ListenerEvent<List<AdminCreateEvent>> event)  {
    log.debug("listener: {}", event);
   // Thread.sleep(30_000)
}

PetricHwang avatar Mar 19 '24 02:03 PetricHwang

By default, Jackson is used to serialize the event objects to String so that they can be persisted into the database. Given you have generics and a complex type arrangement involved here, I assume that Jackson does not properly serialize that into the database so that it cannot reconstitute the object instance later.

Please either make sure that Jackson can fully serialize and deserialize all event instances properly, or replace the default EventSerializer with one that uses a different format, not losing the type information.

odrotbohm avatar Mar 19 '24 06:03 odrotbohm

I think this is quite common. I also encountered these problems and it forced me to use simple types.

matiwinnetou avatar Mar 19 '24 09:03 matiwinnetou