2012-07-13 165 views
2

我正在寫一個小clojure pub/sub界面。它非常準確,只有兩種實際使用的方法:do-pub和sub-listen。子偵聽需要一個字符串(一個子名),do-pub需要兩個字符串(一個子名和一個值)。Clojure:需要架構建議

我在clojure還是比較新的,並且遇到了一些麻煩,想出了一個可行的方法來做到這一點。我首先想到的(實際上是我的第一個執行)使用其持有的哈希單一代理:

{ subname (promise1 promise2 etc) } 

當一個線程要分呢連詞是一個承諾對象就是了子相關聯的列表,然後立即嘗試取消引用該承諾(因此阻止)。

當一個酒吧發生時,它會遍歷該列表中的每個項目並將該值傳遞給該項目(承諾)。然後它從地圖中解析出該子名並將其返回給代理。

以這種方式,我得到了一個簡單的酒吧子實現工作。但是,如果有人下潛,在一段時間內沒有收到酒吧,則會因爲超時而被殺。在這種情況下,代理中會有一個不值錢的承諾,而且如果該子從不被髮布,這將成爲內存泄漏的來源。

有沒有人有任何想法如何解決這個問題?或者,如果有更好的方法來做我想要做的事情(我試圖避免使用任何外部預煮熟的pubsub庫,這是一個寵物項目不是工作)?

回答

3

你可以做這樣的事情:

  • 創建​​
  • publish功能會更新的值傳遞給函數
  • 認購原子值可以使用add-watch上的原子是通知原子值何時發生變化,即由於致電publish函數
  • 使用remove-watch刪除訂閱。

這樣你就會有一個非常基本的pub-sub系統。

3

我已經標記了Ankur的答案作爲解決方案,但我想稍微擴展一下。我最終做的是擁有一箇中心原子,所有客戶端線程開啓add-watch。當一個pub被完成時,atom的值被改變爲一個包含sub的名字和被髮布的值的向量。

客戶端傳遞給add-watch的功能是一個局部函數看起來像

(partial (fn [prom sub key ref _old new] ...) sub prom) 

其中PROM是先前產生的一個承諾。客戶在等待承諾時阻塞。部分函數檢查new中的子項是否與sub相同,如果是,則刪除手錶並從new開始執行承諾。