将 IgniteCursor[T]/Iterable[T] 转换为 Future[Seq[T]]

Transform an IgniteCursor[T]/Iterable[T] to Future[Seq[T]]

使用 Scala,如何将 Iterable[t] 转换为 Future[Seq[T]]

基本上我想读取 Apache Ignite 上的查询返回的所有值,即 returns 和 IgniteCursor.

我想以非阻塞方式从该游标读取数据。

我会写:

val iterable = cursor.asScala
val result = iterable.toList

Future{
  result
}

但我认为这段代码是阻塞的,而不是异步的。我说的对吗?

Iterable 转换为 Future[Seq] 有意义吗?

更新

我的目标是在不阻塞调用者线程或工作线程的情况下获取一小部分记录,因为我会收到许多并发调用。

我的 Iterable 实际上是一个 IgniteCursor 所以我想它在内部会执行一些 network/database 操作。 通常有一些方法可以异步执行这些操作。 例如,要读取单个值,我可以使用 getAsync 而不是 get.
对于游标,我只有 getAll 功能,所以我的想法是巧妙地使用 Iterable
我的理解是,当使用异步方法时,线程不会被阻塞,但它们可以自由执行其他任务,直到网络操作完成。 我希望有一个 returns Future/IgniteFuture 或回调函数。
有没有一种方法可以在不阻塞线程的情况下获取所有记录?

最后,为了正确释放资源,我需要调用 close 函数。如果我写 Future(cursor.asScala.toList) 应该什么时候调用 close 方法?在Future?

onComplete

另一个简单的解决方案是写 Future{cursor.getAll.asScala} 但我想内部工作线程将被阻塞以等待所有记录。

也许我漏掉了什么?

更新 2

换句话说,有一种方法可以使用 "Asynchronous Non-Blocking IO"?

从 Ignite 获取记录列表

Does trasforming an Iterable to a Future[Seq] make sense?

这取决于您的目标。

Iterable 是懒惰的并且内存效率高。 Seq急切,会占用较多内存。从 IterableSeq 你实际上是在说:"I don't want to see any data until everything is ready and loaded into memory."

通过将其设为 Future[Seq],您实际上是在说:"I'll come back later after (hopefully) all the data elements are ready and loaded into memory."

我不明白。如果你只有 getAll,那么 "smart" 你怎么可能得到它?您有两个选择:将其称为内联,或卸载到线程。

您可以做的一件事是将调用包装成 blocking

Future { 
   blocking { 
      cursor.getAll.asScala
   }
}

这告诉执行程序,工作线程将阻塞,因此它不会将其计入线程池限制。 阻塞本身并不坏。只有当它导致线程饥饿时才糟糕。

但要小心这一点。如果您的游标 "heavy",并且有很多游标 运行 并发,那么除了线程阻塞之外,您还会遇到其他问题。 例如,您可能 运行 内存不足,因为您将尝试一次将所有结果放入其中。否则你会使 IO 饱和。