简体   繁体   English

Mutiny - 将完成传播到父多/轮询

[英]Mutiny - Propagate completion to parent multi / polling

I am writing a little polling mechanism using Mutiny, part of me learning the library and i am kinda stuck in cancelling the polling when result is found.我正在使用 Mutiny 编写一个小轮询机制,我学习图书馆的一部分,当找到结果时我有点卡在取消轮询。 I tried using the tick() and what i came up with looks like我尝试使用 tick() ,我想出的看起来像

Multi.createFrom().ticks().every(Duration.ofSeconds(5))
    .onItem().transformToMultiAndMerge(tick -> {
      System.out.println("Tick:" + tick);
      return Multi.createFrom()
          .<Transaction>emitter(
              emitter -> {
                service.getTransactions().toMulti()
                    .onItem().transformToMultiAndMerge(
                        transactions -> Multi.createFrom().iterable(transactions))
                    .subscribe().with(transaction -> {
                      if (!verification.isOngoing()) {
                        emitter.fail(new TransactionVerificationException());
                      } else {
                        boolean transactionFound = transaction.getAmount().stream().anyMatch(
                            amount -> amount.getQuantity()
                                .equals("test"));
                        if (transactionFound) {
                          emitter.emit(transaction);
                          emitter.complete();
                        } 
                      }
                    });
              });
    })
    .subscribe()
    .with(transaction -> log.info(transaction),
        x -> x.printStackTrace());

Problem here is that the Multi from ticks() is running forever and the only way i think of to cancel it would be to propagate somehow that the emitter has completed.这里的问题是来自 ticks() 的 Multi 永远运行,我想取消它的唯一方法是以某种方式传播发射器已完成。 The case here is that i want to emit, and process only if certain conditions are met.这里的情况是我想发出,只有在满足某些条件时才进行处理。

You approach is almost correct, though,不过,您的方法几乎是正确的,

  • there is no need to create a custom MultiEmitter out of an existing Multi (or transformed Uni ) as you can leverage the different Multi operators on top of your source service#getTransaction result无需从现有的Multi (或转换后的Uni )创建自定义MultiEmitter ,因为您可以在源服务之上利用不同的Multi运算符service#getTransaction结果
  • you missed the EmptyMulti source which will automatically complete downstream subscriber chain and which you can use to signal an absence of valid item (ie Transaction )您错过了EmptyMulti源,它将自动完成下游订阅者链,您可以使用它来表示没有有效项目(即Transaction
  • you need to select the first valid item (being non-null) then transform your Multi to Uni which will result in the upstream subscription being cancelled automatically once an item is received您需要选择第一个有效项目(非空),然后将您的Multi转换为Uni ,这将导致收到项目后自动取消上游订阅

Here down what the stream pipeline would look like:下面是流管道的样子:

Multi.createFrom()
        .ticks()
        .every(Duration.ofSeconds(5))
        .onItem()
        // flat map the ticks to the `service#getTransactions` result
        .transformToMultiAndMerge(tick -> service.getTransactions()
                .toMulti()
                .onItem()
                // flatten Collection<Transaction> to Multi<Transaction>
                .transformToIterable(Function.identity())
                .onItem()
                .transformToMultiAndMerge(transaction -> {
                    if (!verification.isOngoing()) {
                        return Multi.createFrom().failure(new TransactionVerificationException());
                    } else {
                        boolean transactionFound = transaction.getAmount()
                                .stream()
                                .anyMatch(amount -> amount.getQuantity().equals("test"));
                        if (transactionFound) {
                            return Multi.createFrom().item(transaction);
                        } else {
                            return Multi.createFrom().empty();
                        }
                    }
                })
        )
        .select()
        .first(Objects::nonNull)
        .toUni()
        .subscribe()
        .with(transaction -> log.info(transaction), x -> x.printStackTrace());

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM