如何在 Clojure 中按部分生成惰性序列?

2024-02-29

我有一个数据库服务器,我从中获取数据。有时数据有数百万行甚至更多,所以我使用惰性下载。我使用 clojure.jdbc 库中的服务器端游标https://funcool.github.io/clojure.jdbc/latest/#cursor-queries https://funcool.github.io/clojure.jdbc/latest/#cursor-queries延迟获取数据。

现在我有一个问题。我需要从惰性序列中生成初始 500 个元素,然后程序必须等待 10 分钟才能收到向程序报告生成下一个 500 个元素的信号,依此类推,直到我从服务器收到所有数据。但如果 10 分钟内没有收到报告,程序必须关闭连接。

我写了样本:

(def lazyseq_maps (atom {:seq_1 {:next_500 false :data nil} :seq_2 {:next_500 false :data nil}})) ; here is a collection of all unfinished lazy sequences waiting for signal to continue produce elements

(jdbc/atomic conn
 (with-open [cursor (jdbc/fetch-lazy conn sql]
   (let [lazyseq (jdbc/cursor->lazyseq cursor)]
     (swap! lazyseq_maps assoc seq_id {:next_500 true :data nil})
     (loop [lazyseq_rest lazyseq
            count 1]
            (if (:next_500 (seq_id @lazyseq_maps))
              (do
                (swap! lazyseq_maps update-in [seq_id :data] conj (first lazyseq_rest))
                (when (= 0 (mod count 500))
                  (swap! lazyseq_maps assoc-in [seq_id :next_500] false))
                (recur (rest lazyseq) (inc count)))
              ;
              (func-for-waiting-signal)))) ; here I don`t know how to create function waiting signal to continue fetching data
   (seq_id @lazyseq_maps)))

你能帮助我应该使用哪些 clojure 工具来解决我的问题吗?我认为我应该使用 core.async 来创建循环通道。我对吗?如果我收到适当的信号,我应该如何创建停止执行循环 10 分钟或继续执行的函数?


事实上你应该为此使用 core.async ,他们有timeout https://clojuredocs.org/clojure.core.async/timeout用于超时目的的通道和alt! https://clojuredocs.org/clojure.core.async/alt!您可以“等待”从任意数量的通道中弹出一个值。不过完整的代码会有点复杂。输出行将被“推送”到输出通道。

据我所知with-open并且惰性序列不能很好地组合,因为光标会过早关闭。但我不熟悉 clojure.jdbc 库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Clojure 中按部分生成惰性序列? 的相关文章