我在两个进程中使用congomongo库。其中一个进程与数据库连接而没有错误。另一个过程遇到了更多麻烦。如果我尝试从那个进程slime repl与数据库交互,它也没有问题,但如果我尝试通过telnet进行交互,那么事情就会很糟糕。
命令行:
joshua@joshua-Aspire-5251:/data/db$ telnet localhost 4576
Trying ::1...
Connected to localhost.localdomain.
Escape character is '^]'.
http://news.ycombinator.com/item?id=2286907
Connection closed by foreign host.
服务器的反应
http://news.ycombinator.com/item?id=2286907
Processing link.
Validating link.
Scraping item.
Wikifying items.
Uploading items.
来自REPL:
(process-link "http://news.ycombinator.com/item?id=2286907")
服务器的反应:
http://news.ycombinator.com/item?id=2286907
Processing link.
Validating link.
Scraping item.
Wikifying items.
Uploading items.
唯一的功能区别?一个实际上将项目放在数据库中,而另一个则没有。两者似乎都在完成其他一切。
(ns hnparser.main
(:use somnium.congomongo
[hnparser.core :only [scrape-item]]))
(mongo! :db "hacker-archives")
(defn valid-link?
[link]
(do
(println "Validating link.")
(not= nil (re-matches #"http://news\.ycombinator\.com/item\?id=\d+" link))))
(defn wikify [item]
(dissoc (assoc item :wiki [{:title (:title item)
:author (:user item)
:body (:body item)
:date (:date item)
:reason "Original post."}])
:title :user :body :date))
(defn wikify-items [items]
(do
(println "Wikifying items.")
(map wikify items)))
(defn upload-item
[item]
(if (nil? (fetch-one :items :where {:id (:id item)}))
(insert! :items (assoc item :scrape-date (java.util.Date.)))))
(defn upload-items
[items]
(do
(println "Uploading items.")
(map upload-item items)))
(defn process-link
[link]
(do
(println "Processing link.")
(if (valid-link? link)
(upload-items (wikify-items (scrape-item link))))))
(ns hnparser.server
(:use clojure.contrib.server-socket
hnparser.main)
(:import [java.io PushbackReader InputStreamReader]))
(defn read-links
[is os]
(let [in-reader (PushbackReader. (InputStreamReader. is))]
(let [input (str (read in-reader))]
(do
(println input)
(process-link input)))))
(defn -main
[]
(def *server* (create-server 4576 read-links)))
请注意,这已成功擦除(通过print语句验证)。它只是不上传到数据库。
答案 0 :(得分:4)
地图很懒:当你想要副作用而不是返回值时,你永远不应该使用地图。您可以使用dorun包装地图,但在大多数情况下,使用doseq更容易。
defn也有隐含的做法,因此(fn [x] (do (println x) (inc x)))
与(fn [x] (println x) (inc x))
相同。