我正在玩future
并且似乎无法使用javax.mail
。例如,为了好玩,我正在尝试设置一个compojure处理程序来抓取一堆电子邮件并将它们放入数据库中,但在收集和插入电子邮件之前向客户端发送响应。
我在println
函数(下面)中有几个import-posts
,当我从repl运行它时,它工作正常,第一次打印142 journal messages.
(因为db是空的),第二次是No new messages.
。当我通过运行本地开发jetty服务器来尝试它时,每次加载页面时都会得到println
142 journal messages
输出,并且它们永远不会插入到数据库中。好的,那么我尝试将它们从repl导入数据库,然后然后从jetty尝试它,我每次都得到142 journal messages
。实现这一目标的最佳方法是什么?
(GET "/" request
(if-let [usr_id (:id (friend/current-authentication))]
(friend/authorize
#{:pojagi.models.usr/user}
;; this is where I'm having trouble
(do (future (let [folder (mail/get-folder mail/gmail "Inbox")]
(println "importing emails from " (.getName folder) ".")
(mail/import-posts usr_id folder)))
(index/home)))
(index/index (:flash request))))
(defn import-posts
[usr_id ^javax.mail.Folder folder & {:keys [subject-term public?]}]
(let [messages (get-latest-messages usr_id folder)
journals (into [] (.search folder (SubjectTerm. (or subject-term "journal")) messages))]
(println (count journals) "journal messages.")
(if (< (count journals) 2)
(println "No new messages.")
(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) )))
答案 0 :(得分:2)
你可能被懒惰的小虫咬伤了:
如果您在doall
周围包裹map
可能有帮助
(doall (map
(fn [journal]
或dorun
如果您不想在之后检查结果(dorun就像doall那样不能保存整个序列,因此不太可能耗尽内存)
(dorun (map
(fn [journal]
当您从repl运行import-posts时,repl会打印将fn [journal]
映射到日志上的结果,这会导致将它们插入数据库的副作用。 当jetty运行时,没有看到结果,序列仍然懒惰 - 未实现,副作用不会发生。
答案 1 :(得分:1)
在尝试for
因为我的内存不足之后,我终于发现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))))