multithreading - future 无法使用 javax.mail

标签 multithreading clojure jakarta-mail future

我正在玩future,但似乎无法让它与javax.mail一起工作。例如,为了好玩,我尝试设置一个 compojure 处理程序来抓取一堆电子邮件并将它们放入数据库中,但在收集和插入所有电子邮件之前向客户端发送响应。

我在 import-posts 函数中进行了一些 println 操作(如下),当我从 repl 运行它时,它工作正常,打印 142 日志消息。 第一次(因为数据库为空),没有新消息。 第二次。当我通过运行本地开发jetty服务器进行尝试时,每次加载页面时都会得到142日志消息println输出,并且它们永远不会插入到数据库中。好的,然后我尝试将它们从 repl 导入数据库,然后从 jetty 尝试,每次仍然收到 142 条日志消息。实现这一目标的最佳方法是什么?

compojure 处理程序:

(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) )))

最佳答案

你可能被懒虫咬了:

如果你在 map 周围包裹一个doall,它可能会有所帮助

(doall (map
    (fn [journal]

或者dorun如果你不想检查之后的结果(dorun就像doall一样,不保存整个序列,所以不太可能耗尽内存)

(dorun (map
    (fn [journal]

当您从 repl 运行 import-posts 时,repl 会打印在期刊上映射 fn [journal] 的结果,这会导致将它们插入数据库的副作用。 当jetty运行时,什么都不看结果,序列保持延迟未实现,并且不会发生副作用。

关于multithreading - future 无法使用 javax.mail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17436762/

相关文章:

java如何通过任何帐户发送电子邮件

java - 如何将 PST 文件中的所有或选定的电子邮件和电子邮件附件提取到本地文件夹中?

java - 从独立应用程序轮询 GMail 收件箱中传入邮件的正确方法

java - MongoDB 池超时

java - 强制执行打印顺序,但线程在一次迭代后彼此等待

java - 在线快速手册 : REST API or Java SDK?

Clojure:如何替换嵌套列表中的元素?

macros - 传递给宏的变量在错误的命名空间中被解析?

c++ - 具有纯虚拟回调的线程基类,在销毁时停止 c++

windows - 了解 MsgWaitForMultipleObjects