Как создать ленивую последовательность по частям в clojure?
У меня есть сервер базы данных, и я получаю данные с него. Иногда данные имеют миллионы строк и более, поэтому я использую лень для загрузки. Я использую серверные курсоры из библиотеки clojure.jdbc https://funcool.github.io/clojure.jdbc/latest/ для ленивого извлечения данных.
Теперь у меня проблема. Мне нужно произвести начальные 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 минут или продолжит выполнение, если я получу соответствующий сигнал?
1 ответ
На самом деле вы должны использовать core.async для этого, у них есть канал тайм-аута для цели тайм-аута и с alt! Вы можете "подождать", пока значение не появится из любого количества каналов. Полный код будет немного сложным, хотя. Выходные строки будут "выталкиваться" в выходной канал.
Насколько мне известно with-open
и ленивые последовательности не составляются хорошо, поскольку курсор будет закрыт преждевременно. Но я не знаком с библиотекой clojure.jdbc.