2010-10-05 72 views
2

我的問題很簡單:事件驅動編程實際上是如何實現的?事件驅動編程是如何完成的?

要說明一下:我有一個Rails應用程序,每一個用戶對網站上的變化時,該模型寫道,「變」到一個文本文件(JSON)

我想什麼do是把一個IRC bot掛到那個「事件」上。 (創建/修改文本文件)。

這是如何完成的?它似乎基本上是一個無限循環。僞代碼:

while (I'm Listening) 
do 
    if (output.txt Is changed) 
    process("output.txt") 

如果這是事件驅動編程如何實現 - 它如何避免鎖定CPU?由於無限循環有這樣的傾向嗎?

編輯- IRC服務器/機器人託管在本地維護的盒子上。 Rails應用程序託管在共享服務器上。到目前爲止,我知道我的IRC bot與Rails應用程序通信的唯一方式是通過對服務器的HTTP請求(或類似的東西)。正如我所說的,這個問題實際上更普遍,因爲我想以獲得一般事件驅動編程的知識。

我很抱歉,如果這個問題不可能簡單,但我對事件驅動編程的理解包括將預先創建的事件處理程序附加到使用jQuery的對象;當將一個IRC bot(用Ruby寫成)附加到文件I/O時,這確實沒有幫助。

感謝, 羅比

回答

1

也許你應該創建一個DRb server或使用使用此解決方案,如delayed_job。您可以在不同的機器上運行工作人員。通過連接到服務器上的特殊端口進行連接。您只需在防火牆上打開運行IRC bot的專用機器的端口即可。您可以將紅寶石對象放在隊列中,因此可以通過將紅寶石對象放在也包含此更改的隊列中來鏡像每個文件更改。工人會在幾秒鐘後抓住這個,這不會是瞬間的。但它仍然非常快,使用低CPU並且能夠處理網絡中斷。

+0

太棒了,我似乎也可以共享Ruby類本身 - 而不是繞過JSON解釋。感謝你的回答 :)。 – Robbie 2010-10-06 15:34:44

+0

我已經將你的標記標記爲已接受的答案,因爲我現在正在使用分佈式ruby實現,並且它工作得非常好! – Robbie 2010-10-07 20:35:14

4

更多的時候,它是這樣的:

while (I'm Waiting to be notified) 
do 
    if (output.txt Is changed) 
    process("output.txt") 

有在操作系統方面(任何操作系統)來等待沒有考慮CPU時間(通知,如條件)沒有事件驅動的循環坐在那裏旋轉等待事件。

+0

同意。不需要無限循環。監視器應該是一個簡單的阻塞調用,等待更改。 – 2010-10-05 21:09:31

1

通常,您正在描述的while/listener循環的類型是在線程中創建的,例如等待連接的UDP或TCP服務器。但這並不適用於您的擔憂。 Rails和ActiveRecord在ActiveRecord模型中定義了許多內置的Observer-pattern樣式鉤子,這些鉤子可能對您很有用。在這裏看到:http://api.rubyonrails.org/classes/ActiveRecord/Observer.html

如果你真的需要監視外部文件和ActiveRecord的或ActiveRecord的樣式的回調的狀態不適合你,你可以監控與管理的阻擋,而一個簡單的Ruby守護進程文件循環。但我仍然不確定爲什麼你不會簡單地使用修改文件的Rails代碼來通知你的IRC機器人/進程等。

+0

在這個特定的實例中,IRC bot不託管在同一臺服務器上。 – Robbie 2010-10-05 21:10:49

+0

@Robbie - 這是否意味着你在等待HTTP請求呢? – Matchu 2010-10-05 21:15:17

+0

但是,爲什麼不用相同的調用來修改json文件來連續通知機器人?爲什麼顯示器必須是異步的? – 2010-10-05 21:22:22

2

我熟悉的基本模型是通過創建一個類暴露可以訂閱的事件。這可以像一組方法一樣簡單。

class Foo 
    attr_accessor :event #obviously not the right way to do it, but it will suffice 

    def initialize 
    @event = [] 
    end 

    private 
    def fire_event 
    @event.each { |sub| sub.call } 
    end 
end 

現在這個類的客戶端可以傳入他們希望在事件觸發時執行的方法。

f = Foo.new 
f.event << lambda { puts 'event was fired' } 

當Foo類調用fire_event方法時,將執行過程集合中的每個過程。沒有循環不斷檢查一些條件。當條件出現時,調用點火方法並執行程序。

在旁邊注意上面的例子就是這樣;一個例子。現實世界的事件架構將更加強大,但是它們將是相似的。這可能甚至不適用於你的實際情況,但我不是一個網絡人,我不知道RoR和JSON以及所有其他奇特的關鍵字,所以我進入了高層。希望它有幫助。

2

我不確定它背後的黑魔法,但流行的Ruby寶石EventMachine有一個watch_file方法,似乎處理您的確切用例。當其他人已經爲你做了這件事時,你不需要做任何事情。

分享和享受。

編輯:您對Dave Sims的回答的評論似乎暗示您的Rails應用程序和IRC bot位於不同的文件系統上,並且該JSON文件通過HTTP提供。如果是這樣的話,無論如何,你都在等待HTTP請求,所以儘可能經常發送一個HTTP請求(儘管我建議採取一些小的暫停來避免擾亂你的服務器)不應該阻塞CPU,因爲它會在等待來自服務器的響應時暫停。如果bot腳本需要同時執行其他操作,則基於EventMachine並使用gem發送基於事件的HTTP請求應該注意這一點。儘管如此,我仍然不完全清楚你在做什麼。

+0

很好找。我會避免在Rails進程的線程中運行這個。也許可以在守護進程模式下查看單獨的超級簡單Ruby進程。 http://daemons.rubyforge.org/ – 2010-10-05 21:23:29

+0

我更新了問題以闡明我的設置。基本上,我的用戶可以創建「滾動」(想象擲骰子),然後IRC機器人會對每個新頻道進行迴應。這只是一種將我的Rails應用程序與「玩家」(坐在IRC頻道中)接口的方式。 – Robbie 2010-10-05 21:25:34

+0

因此,本質上添加某種形式的計時器(或者在此示例中等待HTTP)將允許操作系統工作在其他任務? 所以雖然它是一個「無限循環」,但它永遠不會死亡,它不會吃掉CPU,因爲它不會在每一個週期*上主動地做某件事。 – Robbie 2010-10-05 21:37:29