2012-03-20 19 views
4

我正在開發一個類似SVN的系統(基本上有登錄/註銷+ put/get/list/delete命令),它們應該接受來自多個客戶端的命令。我的想法是將所有接收到的命令放入一個(阻塞)隊列結構中,以便在不同的線程上順序執行它們。後來,有了更多的時間,我可以設計一些智能機制來理解是否可以同時執行一個或多個下一個隊列消息,這樣我可以加快一點過程(例如,如果我有兩個命令隊列將在不同的項目上工作,沒有競爭條件/共享數據問題)。如何更好地在顛覆式系統中同時處理命令?

我現在正面臨決定這是否真的是問題的最佳解決方案的問題。我可以鎖定文件,因爲我正在使用它們,但是我擔心這可能會導致某些特定的角落案例出現死鎖(儘管我仍然無法想到可能發生的具體情況)。

該項目將用於網絡安全類。因此,這個SVN只是我後來奠定我的安全問題核心的基礎。我不認爲性能是最重要的(但要確保死鎖不會發生YES!),所以目標是算法的正確性。

你會如何處理這種情況?

+0

跳過平常的「不要重新發明輪子」的說法,鎖定文件級別應該足以滿足您的需要;如果您不將鎖定請求拆分爲按文件粒度(但爲什麼不呢?),它只會死鎖。 – Viruzzo 2012-03-20 18:49:37

+0

當我做一個PUT「abc.txt」時,我在資源庫中創建了一個名爲「abc.txt」的文件夾,每個文件的文件爲0,1,2,3,...(這是一個拼版,不是我可以做很多事情)。所以我有點害怕,當在不同版本上進行操作時,我可能會有2個客戶想要在不同的版本上同時操作。 – 2012-03-20 18:55:00

+0

@devouredelysium:我相信我不會相信你的觀點。客戶端可以在「服務器」上「提交」同一文件的多個版本。但是,如果這是「像系統一樣」,爲什麼你擔心在這種情況下的協調性。在處理大量數據所需的操作之前,請檢查批量中是否已有更新版本的*任何*組件。你能否澄清更多你的情況? – Tigran 2012-03-20 19:05:32

回答

1

我已經完成了幾個類似性質的項目。在一次迭代中,我們先將這些文件複製到服務器上,然後再將它們傳輸到客戶端。而對於相反的方向,我們在覆蓋主文件之前流式傳輸到臨時文件。這是一團糟。不要這樣做!目前典型的互聯網連接速度並不比磁盤慢,典型的磁盤傳輸速度通常比平均LAN連接速度慢。另外,你是否在這個東西中存儲(通常是小的)源代碼文件?文件鎖定將足以保護文件。現在每個庫都支持系統級文件鎖定。 (如果你不相信我,請查看.Net中FileStream的構造函數重載。)如果需要寫入數據,則嘗試獲取所有必需文件的寫鎖。如果無法完成,則向用戶返回超時錯誤。我工作的一個系統具有永久性的只讀文件,如果您希望人們能夠整天傳輸某個文件,那麼您可以使用該標誌來完成此操作。如果文件鎖確實不足,可以查看.Net ReaderWriterLock類。

我看不出手動排隊您的put/get/delete請求的好處。這是服務器的工作,而不是你的工作。你不想把所有的「put」數據放在RAM中。如果可能的話,你絕對不想管理自己的上傳流。 (我們必須編寫自己的原生IIS 7處理程序,用於文件上傳大於2GB,這是一個PITA。)您是否熟悉WCF中的併發和實例模型? (如果沒有,你可能會從這裏開始:http://msdn.microsoft.com/en-us/library/ms731193.aspx)我最熟悉這一點,但我認爲其他服務器框架具有類似的配置。我可以看到緩存列表數據的一些優點,以便在此情況下爲您節省潛在的磁盤空間。在我工作的其中一個項目中,我們緩存了NT域登錄令牌。這最終成爲一種痛苦和責任,完全沒有必要。我認爲現有的管理會話和服務器端權限的框架就足夠了。

+0

」而對於相反的方向,我們在覆蓋主文件之前流入臨時文件,這是一團糟,不要這樣做!「我實際上是在服務器上這樣做,因爲我認爲它會更安全,以防萬一我上傳文件時出現任何問題。這有什麼問題? – 2012-03-21 06:29:21

+0

「我看不出手動排隊你的put/get/delete請求的好處。」但我正在開發客戶端和服務器! – 2012-03-21 06:29:56

+0

我認爲可以上傳到臨時文件,只要您可以保證臨時文件與最終目的地位於同一個驅動器上即可。事實上,將它放在與最終目的地相同的文件夾中,並帶有一個奇怪的擴展名。 (Web瀏覽器就是這樣做的)。你不想做的是讓用戶配置臨時文件的位置。如果他們可以配置文件的存儲位置,請不要使用%TEMP%。在這兩種情況下,您最終都會將臨時文件轉到其他驅動器。這意味着「複製」而不是「移動」,這是我們想要避免的。 – Brannon 2012-03-23 20:05:35