方法rxExecuteBlocking消耗所有结果 - ssh client

时间:2017-08-08 10:37:16

标签: java ssh rx-java vert.x

我试图用Vert.x做一个非常简单的SSH客户端。由于我没有非阻塞的SSH库,我必须处理rxExecuteBlocking中的所有内容。当我在一大块代码中运行所有逻辑时,它工作得很好,如下所示:

public Single<String> exec() {
   return vertx.rxExecuteBlocking(f -> {
       String result = "";

       // connect()
       // exec()
       // close()

       f.complete(result);
   }, false);
}

// hostnames :: Observalbe<String>
hostnames()
  .filter()
  .flatMapSingle(this::exec)
  .moreCalls()
  .subscribe(); // OK

我宁愿让connect()exec()close()分开并致电:

hostnames()
  .filter()
  .flatMapSingle(this::connect)
  .moreCalls()
  .flatMapSingle(this::exec)
  .moreCalls()
  .flatMapSingle(this::close)
  .subscribe();

但是当运行多个阻止代码时

public Single<Connection> connect() {
  return vertx.rxExecuteBlocking(f -> {
     // connect
  }, false);
}

public Single<Connection> exec() {
  return vertx.rxExecuteBlocking(f -> {
     // exec
  }, false);
}

链在flatMapSingle(this::connect)处停止,首先消耗filter()的所有结果(建立所有连接),然后继续链接。此行为消耗了相当多的资源,因为所有连接都在内存中(此行为提醒我reduce()collect()

所需的结果将不会在链中停止并继续,释放资源并为每个事件执行此操作。

有没有办法做到这一点?

提前致谢。

1 个答案:

答案 0 :(得分:0)

我建议尝试使用重载flatMap,它将特定管道阶段的并发订阅的可观察量的最大数量作为参数。如果默认情况下工作线程池中有20个线程,则可以为每个flatMap调用提供一小部分池,例如每个人5个。

hostnames()
  // ...some filtering
  .flatMap(hostname -> this.connect(hostname).toObservable(), 5)
  // ...more operators
  .flatMap(connection -> this.exec(connection).toObservable(), 5)
  // ...more operators
  .flatMap(connection -> this.close(connection).toObservable(), 5)
  .subscribe();

这将确保不会在同一时刻使用整个线程池。

可能需要对并发加载进行一些调整。例如,如果connectexec快,connect的{​​{1}}和exec的同时订阅的可观察量较少。因此,connect之前的exec的结果不会堆叠在缓冲区中。