如何在Spring Webflux中避免两次阅读正文?

时间:2019-05-19 20:52:13

标签: kotlin spring-webflux project-reactor reactor-netty

我体内有一个对象MultiMeasurement,具有一个状态和1n的测量值。

我必须将状态和度量保存在存储库中,并与它们一起发出事件,并从端点返回正确的响应。

fun save(multiMeasurement: Mono<MultiMeasurement>) =
    multiMeasurement.map(MultiMeasurement::validate)
        .flatMapMany { measurementCollector.save(it) }
        .doOnNext { eventSender.sendEvent(it.toMeasurementItem()) }
        .then(statusFacade.save(multiMeasurement))
        .doOnNext { eventSender.sendEvent(it.toStatusUpdateItem()) }
        .flatMap { toSettings(it.deviceId) }

以下代码的问题是正文被读取了两次-首先在map运算符中,其次在then内部。

两者-statusFacademeasurementCollector以反应方式(mongo)保存对象并返回适当的Mono

onOperatorDebug的结果:

|_  Mono.flatMap ⇢ com.openbrewery.beerbob.status.StatusCollector.save(StatusCollector.kt:15)
|_  Flux.then ⇢ com.openbrewery.beerbob.measurement.MeasurementFacade.save(MeasurementFacade.kt:21)
|_  Mono.doOnNext ⇢ com.openbrewery.beerbob.measurement.MeasurementFacade.save(MeasurementFacade.kt:22)
|_  Mono.flatMap ⇢ com.openbrewery.beerbob.measurement.MeasurementFacade.save(MeasurementFacade.kt:23)

是否可以读取一次正文并在measurementCollectorstatusFacade中重新使用它?

1 个答案:

答案 0 :(得分:0)

您可以尝试flatMap multiMeasurement单声道,它将读取一次主体。在flatMap内部,其余代码应该非常相似。应该是这样的:

fun save(multiMeasurement: Mono<MultiMeasurement>) = multiMeasurement
    .flatMap { mm ->
        measurementCollector
            .save(mm.validate())
            .doOnNext { eventSender.sendEvent(it.toMeasurementItem()) }
            .then(statusFacade.save(mm))
            .doOnNext { eventSender.sendEvent(it.toStatusUpdateItem()) }
            .flatMap { toSettings(it.deviceId) }
    }

在您的代码中,multiMeasurement mono被订阅了两次,这就是您两次阅读正文的原因。为了避免这种情况,您需要对Mono的值进行一次平坦化处理,然后再将实际值向前传递。