2

私は と で遊んでいてfuture、 で動作させることができないようですjavax.mail。たとえば、楽しみのために、compojure ハンドラーをセットアップして、一連の電子メールを取得してデータベースに入れようとしていますが、電子メールがすべて収集されて挿入される前に、クライアントに応答を配信します。

関数 (以下) でいくつかprintlnの s がimport-posts実行されています。これを repl から実行すると142 journal messages.、最初は (db が空であるため)、No new messages.2 回目は正常に出力されます。ローカル開発の jetty サーバーを実行して試してみると、ページをロードするたびにprintln出力が得られ、db に挿入されません。さて、私はそれらをreplからdbに142 journal messagesインポートしてからjettyから試してみましたが、それでも毎回得られました。これを達成するための最良の方法は何ですか?142 journal messages

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

2 に答える 2

2

あなたは怠惰なバグに噛まれたかもしれません:

doallあなたが周りを包むなら、mapそれは助けになるかもしれません

(doall (map
    (fn [journal]

またはdorun、後で結果を確認したくない場合 (dorun は doall のようなもので、シーケンス全体を保持しないため、メモリ不足になる可能性が低くなります)

(dorun (map
    (fn [journal]

repl から import-posts を実行すると、replfn [journal]はジャーナルをマッピングした結果を出力します。これにより、ジャーナルがデータベースに挿入されるという副作用が生じます。jetty が実行されると、何も結果が表示されず、シーケンスは遅延して実現されず、副作用は発生しません。

于 2013-07-02T22:32:22.070 に答える