2011-07-27 77 views
4

這是我的情況,我有一個外部程序,每30 ms左右發送一次數據給我。該數據被合併到參考文獻中。扼殺更新頻率的想法

在這一點上我有,

(def state (ref {}) 

一個單獨的未來讀取和合並數據包此Ref。

現在我有了我的狀態機,即做出決定併發回控制命令。基本上每個狀態具有以下結構,

 


(while (some-thing-happening) 
    (calc-stuff) 
    (send-correction)) 
 

這是我的問題,如果我接收100個分組/秒有在發送200個命令/秒沒有意義的。所以我想提出一個可以抑制更新率的方案。我無法爲某些ms睡眠導致更新率不確定。你將如何構造這個?

回答

0

當您更改參考時,調用狀態機功能。這樣,您可以以與數據更改相同的速率發送命令。

或者,使用另一個ref作爲標誌並在更新數據時將其設置爲true,將該標誌作爲條件添加到while循環中。更新後重置爲false。

+0

狀態機從未實際返回。 –

1

首先,您需要一種措施來防止沒有數據到達時的工作。您可以通過

  1. 接收數據包到達時的回調,從而提升您的狀態機。使用它,如果你的IO API有回調。
  2. 阻止在some-thing-happening直到一個數據包到達。如果API允許並且沒有回調,請使用它。
  3. 將傳入數據包寫入BlockingQueue並從您的狀態機讀取。這模擬2.

其次,你可能希望將狀態模型作爲代理人:

(def state (agent {})) 

這樣一來,你可以說

(defn update-state [state data] 
    ; e.g. 
    (merge state data)) 

;; in the state machine 
(send state correct data) 

這在更新你的狀態一個單獨的線程。


你甚至可以直接從那裏你看到它們並在update-state實施狀態機送包到代理。

+0

我試過代理,問題是如果我不能夠在一段時間內處理數據包足夠快,我需要做沉重的cals,我想把它們與代理放在一起,如果代理忙,會發生什麼我開始發送100/200毫秒前發生的事情的更正。 –

+0

基本上我想要一個類似於代理的方案,如果它很有意義的話,它將丟棄任何接收到的fn呼叫 –

+0

也許你可以爲你的數據包添加一個時間戳並將它們放入代理中,如果它們太舊。 – Bendlas