I got the following stacktrace using quarkus smallrye reactive messaging with kafka :
2020-07-24 01:38:31,662 ERROR [io.sma.rea.mes.kafka] (executor-thread-870) SRMSG18207: Unable to dispatch message to Kafka: io.smallrye.mutiny.subscription.BackPressureFailure: Could not emit tick 211 due to lack of requests
at io.smallrye.mutiny.operators.multi.builders.IntervalMulti$IntervalRunnable.run(IntervalMulti.java:83)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
So I ve read https://smallrye.io/smallrye-mutiny/#_how_do_i_control_the_back_pressure
According to the documentation I ve add BackPressure control.
Before :
@Outgoing( "eqs-crossing-xxx" )
public Multi< EQSAlert > eqsCrossingXXX_XXX(){
final String series = CrossingEnum.XXX_XXX.getSeries();
final String equipment = CrossingEnum.XXX_XXX.getEquipment();
final String vehicleRegex = vehicleRegexService.getRegexBySeries( series );
log.info( "Incoming request for {} - {}", series, equipment);
log.info( "Vehicle regex : {}", vehicleRegex );
return Multi
.createFrom()
.ticks()
.every(
Duration.ofSeconds( poolingInterval )
)
.concatMap(i -> {
final Multi<CrossingState> crossingStateBySeriesAndEquipment = CrossingState.getCrossingStateBySeriesAndEquipment(client, series, equipment);
return crossingStateBySeriesAndEquipment.flatMap(crossingState ->
crossingState.isActive() ?
EQSAlert.getEQSAlertBySeriesAndEquipment(
client,
series,
vehicleRegex,
equipment
)
:
Multi.createFrom().empty()
);
});
}
After :
@Outgoing( "eqs-crossing-xxx" )
public Multi< EQSAlert > eqsCrossingXXX_XXX(){
final String series = CrossingEnum.XXX_XXX.getSeries();
final String equipment = CrossingEnum.XXX_XXX.getEquipment();
final String vehicleRegex = vehicleRegexService.getRegexBySeries( series );
log.info( "Incoming request for {} - {}", series, equipment);
log.info( "Vehicle regex : {}", vehicleRegex );
return Multi
.createFrom()
.ticks()
.every(
Duration.ofSeconds( poolingInterval )
)
.onOverflow()
.buffer(10)
.concatMap(i -> {
final Multi<CrossingState> crossingStateBySeriesAndEquipment = CrossingState.getCrossingStateBySeriesAndEquipment(client, series, equipment);
return crossingStateBySeriesAndEquipment.flatMap(crossingState ->
crossingState.isActive() ?
EQSAlert.getEQSAlertBySeriesAndEquipment(
client,
series,
vehicleRegex,
equipment
)
:
Multi.createFrom().empty()
);
});
}
And now evrything is ok.
The purpose of my post is to understand why I need to do it ?
Why the buffer can't keep u ?
As you can see I do a simple sql function call every 5s (poolingInterval). The function returns some records (never more than 10 by pooling)
So the traffic is very low
May I have some words to understand the buffer management please.
Thank you