简体   繁体   English

如何重新分配反应通量 stream 中的变量?

[英]How to reassign a variable in reactive Flux stream?

I'm sending requests to a webservice, transform the results into a large csv and persist the csv lines into a database.我正在向 Web 服务发送请求,将结果转换为大型csv并将 csv 行保存到数据库中。

As the requests are long running (10-20s), I want to parallelize the requests.由于请求长时间运行(10-20 秒),我想并行化请求。 I collect all the data in a single StringBuilder that holds the transformed csv lines.我在单个StringBuilder中收集所有数据,该 StringBuilder 包含转换后的 csv 行。

Question: if my chunks of 1000 lines is reached within the csv, how can I take the data out for persistence, while any other concurrent response will be written to a new StringBuilder ?问题:如果在 csv 中达到了我的 1000 行块,我怎样才能将数据取出以进行持久化,而任何其他并发响应都将写入新的StringBuilder

Because, final variables for a stream cannot be reinitialized.因为,无法重新初始化 stream 的最终变量。

final StringBuilder sb = new StringBuilder();
AtomicInteger count = new AtomicInteger();

Flux.fromIterable(requests)
    .flatMap(req -> {
        return webClientService.send(req); //assume long running response
    }, 8) //send 8 requests in parallel, as response takes up to 10s
    .map(rsp -> {
        //convert response to csv values and add to StringBuilder
        int c = addCsv(sb, rsp);
        if (count.addAndGet(c) > 1000) {
            //TODO how can I assign a new StringBuilder,
            //so that all further finished responses will append the csv to the new builder?
            //same problem with the counter.
            
            databaseWriter.write(sb.build()); //writes the content so far to db, but not threadsafe so far
        }
        return c;
    })
    .blockLast();
    

Perhaps you could try to avoid side-effects entirely instead, eg with something like:也许您可以尝试完全避免副作用,例如:

.map(x -> toCsv(x))
.reduce((a, b) -> {
    if (length(a) < 1000) {
        return concat(a, b);
    }
    databaseWriter.write(a);
    return b;
})
.doOnNext(x -> databaseWriter.write(x))

In my opinion, you can use builtin operators to achieve the same result:在我看来,您可以使用内置运算符来实现相同的结果:

      Flux.fromIterable(requests)
            .flatMap(req -> webClientService
                    .send(req)
                    .subscribeOn(Schedulers.boundedElastic()), 8)// subscribeOn to subscribe from different threads
            .map(resp -> converToCsvLine(resp)) //make some transformations on the respnse
            .window(1000) //split incoming data into 1000 lines
            .flatMap(stringFlux -> stringFlux.collect(Collectors.joining("\n")))// collect last 1000
            .flatMap(s -> Mono.fromRunnable(() -> writeToDb(s))) //do some logic on the collected 1000 lines
            .blockLast();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何返回包含 Reactive Mono 和 Flux 的 Reactive Flux? - How to return a Reactive Flux that contains a Reactive Mono and Flux? 如何使用Spring Reactive修改助焊剂的结果 - How to modify results from a Flux with Spring Reactive 如何构建可避免嵌套Flux块的反应式架构(Flux <Flux <T> &gt;)? - How to build reactive architecture that will avoid nested Flux blocks (Flux<Flux <T>>)? 如何重新分配存储在 java 中的 object 中的数组变量 - how to reassign array variable stored in an object in java 如何重新分配和增加字符串变量的值 - How to reassign and increase the value of string variable 重新分配输入/输出流? - Reassign input/output stream? Java 反应式。 如何等待所有变化中的数据然后处理它们 - Java Reactive. How to wait for all data in flux and then process them 如何通过Spring WebFlux Reactive方法在处理函数中使用Mono和Flux - How to use Mono and Flux in handler functions with Spring WebFlux Reactive ways 如何在 java 反应式中为通量 / mono 调用多个服务? - How to invoke multiple services for a flux / mono in java reactive? 当使用application / stream + json时,Spring Reactive WebFlux报告空流量 - Spring Reactive WebFlux reports empty flux when using application/stream+json
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM