Multithreading future不使用javax.mail
我正在玩Multithreading future不使用javax.mail,multithreading,clojure,jakarta-mail,future,Multithreading,Clojure,Jakarta Mail,Future,我正在玩future,似乎无法让它与javax.mail一起工作。例如,为了好玩,我尝试设置一个compojure处理程序来抓取一堆电子邮件并将它们放入数据库,但在收集和插入所有电子邮件之前向客户端发送响应 我在import posts功能(如下)中有一些println正在进行,当我从repl运行此功能时,它工作正常,第一次打印了142条日志消息。因为数据库是空的,没有新消息。第二次。当我通过运行本地开发jetty服务器进行尝试时,每次加载页面时,我都会得到println输出的142条日志消息,
future
,似乎无法让它与javax.mail
一起工作。例如,为了好玩,我尝试设置一个compojure处理程序来抓取一堆电子邮件并将它们放入数据库,但在收集和插入所有电子邮件之前向客户端发送响应
我在import posts
功能(如下)中有一些println
正在进行,当我从repl运行此功能时,它工作正常,第一次打印了142条日志消息。因为数据库是空的,没有新消息。
第二次。当我通过运行本地开发jetty服务器进行尝试时,每次加载页面时,我都会得到println
输出的142条日志消息
,而且它们永远不会被插入数据库。好的,然后我试着从repl将它们导入db,然后从jetty尝试,每次我仍然得到142条日志消息。实现这一目标的最佳方式是什么
复合处理程序:
导入电子邮件的功能:
(defn导入帖子)
[usr_id^javax.mail.Folder文件夹&{:keys[subject term public?]}]
(让[消息(获取最新消息usr_id文件夹)
日记账(进入[](.search文件夹(主题词(或主题词“日记”))邮件))]
(println(计数日记账)“日记账消息”)
(如果(<(盘点日记帐)2)
(println“无新消息”)
(地图
(fn[期刊]
(打印“插入日记账”(.getSubject日记账))
(让[[title-created-bodyparts-uid:as-post][(.getSubject-journal)
(->journal.getSentDate.getTime(java.sql.Timestamp.))
(->journal.getContent)
(->文件夹(.getUID日志))]
车身(->(.getBodyPart车身部件0)
.getDataHandler.getInputStream slurp md/md到html字符串)]
(post/insert{:title:body body:created:usr_id 4:public true:email_id})
))
期刊))
您可能已经被懒惰的bug咬到了:
如果将doall
包裹在map
周围,可能会有所帮助
(doall (map
(fn [journal]
或者
dorun
如果您不想在之后检查结果(dorun类似于doall,不保存整个序列,因此不太可能耗尽内存)
当您从repl运行导入文章时,repl会打印将
fn[journal]
映射到日志的结果,这会导致将日志插入数据库的副作用。当jetty运行这个程序时,什么都不看结果,这个序列仍然懒散地没有实现,副作用也不会发生 由于内存不足,我也尝试了的,最后我发现doseq
对于这种产生副作用的活动来说是一个可行的选择,因为它不会试图将整个集合保存在内存中:
(defn import-posts
[usr_id ^javax.mail.Folder folder & {:keys [subject-term public?]}]
(let [last-uid (post/last-uid usr_id)
messages (get-latest-messages usr_id folder last-uid)
journals (into [] (.search folder (SubjectTerm. (or subject-term "journal")) messages))]
(if (and (< (count journals) 2)
(= last-uid (-> folder (.getUID (first journals)))))
(println "No new messages.")
(doseq [import (map
(fn [journal]
(println "inserting journal" (.getSubject journal))
(let [[title created bodyparts uid :as post] [(.getSubject journal)
(-> journal .getSentDate .getTime (java.sql.Timestamp.))
(-> journal .getContent)
(-> folder (.getUID journal))]
body (-> (.getBodyPart bodyparts 0)
.getDataHandler .getInputStream slurp md/md-to-html-string)]
(post/insert {:title title :body body :created created :usr_id 4 :public true :email_uid uid})))
journals)]
import))))
(defn导入帖子)
[usr_id^javax.mail.Folder文件夹&{:keys[subject term public?]}]
(let[last uid(post/last uid usr\U id)
消息(获取最新消息usr\U id文件夹最后一个uid)
日记账(进入[](.search文件夹(主题词(或主题词“日记”))邮件))]
(如果(和(<(盘点日记帐)2)
(=最后一个uid(->文件夹(.getUID(第一个日记账щщ)]))
(println“无新消息”)
(doseq[导入(映射)
(fn[期刊]
(打印“插入日记账”(.getSubject日记账))
(让[[title-created-bodyparts-uid:as-post][(.getSubject-journal)
(->journal.getSentDate.getTime(java.sql.Timestamp.))
(->journal.getContent)
(->文件夹(.getUID日志))]
车身(->(.getBodyPart车身部件0)
.getDataHandler.getInputStream slurp md/md到html字符串)]
(发布/插入{:标题:正文正文:已创建:usr_id 4:public true:email_id})
期刊)]
(进口)
hehe,这是我对这类常见bug的昵称,因为REPL正在打印结果,所以只在REPL中工作,然后在生产中什么也不会发生。我只是觉得它有一个很好的环:-)事实上,这个答案是有问题的,因为它在27封电子邮件之后停止导入(因为它耗尽了内存)。如果你能避开懒惰和内存不足的问题,你怎么能做到呢?多伦就像多尔一样,不掌握整个过程。我在你的答案中添加了这条评论,并接受了。再次感谢!
(doall (map
(fn [journal]
(dorun (map
(fn [journal]
(defn import-posts
[usr_id ^javax.mail.Folder folder & {:keys [subject-term public?]}]
(let [last-uid (post/last-uid usr_id)
messages (get-latest-messages usr_id folder last-uid)
journals (into [] (.search folder (SubjectTerm. (or subject-term "journal")) messages))]
(if (and (< (count journals) 2)
(= last-uid (-> folder (.getUID (first journals)))))
(println "No new messages.")
(doseq [import (map
(fn [journal]
(println "inserting journal" (.getSubject journal))
(let [[title created bodyparts uid :as post] [(.getSubject journal)
(-> journal .getSentDate .getTime (java.sql.Timestamp.))
(-> journal .getContent)
(-> folder (.getUID journal))]
body (-> (.getBodyPart bodyparts 0)
.getDataHandler .getInputStream slurp md/md-to-html-string)]
(post/insert {:title title :body body :created created :usr_id 4 :public true :email_uid uid})))
journals)]
import))))