2011-09-06 50 views
11

當使用分佈式和可伸縮體系結構時,最終的一致性通常是一項要求。最終一致性的GUI推薦?

從圖形上看,如何處理這個最終的一致性?

用戶被用來點擊保存,並立即看到結果......最終一致性是不可能的。

如何處理這種場景的GUI?

請注意這個問題同時適用於桌面應用程序和Web應用程序。

PS:我與微軟平臺的工作,但我想這個問題適用於任何技術...

+0

[CQRS - 最終一致性]的可能重複(http://stackoverflow.com/questions/3414277/cqrs-eventual-consistency) –

回答

7

一個Task Based UI適合這種模式極大。您可以從UI創建並執行任務。你也可以有一個像任務狀態監視器一樣的東西來顯示用戶何時執行任務。

另一種選擇是使用某種客戶端池。您從客戶端發送命令和池,直到命令完成並且新數據可用。在某些情況下,從用戶按下保存時到他將看到新記錄時,您將會有延遲,但在大多數情況下,它應該幾乎是同步的。

另一個(好?)選項是承擔/設計不失敗的命令。這不是微不足道的,但您可以在客戶端擁有一個緩存,並將命令中的數據添加到該緩存,並在命令執行之前將其顯示給用戶。如果命令在某些意外情況下失敗了,那麼只需設計一個好的「我們很抱歉」的消息來誤導用戶幾秒鐘。

你也可以結合上面的方法。

通常最終一致性更多的是商業/領域問題,您應該由您的領域專家處理它。

+0

不幸的是,「基於任務的用戶界面」鏈接現在已被打破。 –

+0

顯然,cqrsinfo.com域名已丟失至垃圾郵件。這[鏈接](http://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf)似乎有一個捆綁到一個pdf文件的集合 –

+0

看來,基於任務的用戶界面文件現在[這裏] (http://cqrs.wordpress.com/documents/task-based-ui/) –

3

有2種方式:

  1. 誘騙用戶(只是爲了表明事情已經發生了那麼他們真的 尚未發生)
  2. 顯示該系統正在處理請求 和使用輪詢在背景中(不好)或只有定時器的值爲 您的SLA。

我更喜歡第一個選項。

+0

中的鏈接,如果適用的話,第1條似乎對用戶感覺很好。根據適用情況,我想我必須以高成功率(可能95%)發佈命令爲目標,並提供錯誤的異步回調消息。 –

+0

是的,你應該提供儘可能高的成功命令百分比 – xelibrion

2

正如有人已經提到的那樣,基於任務的用戶界面非常適合這種情況,而我所要做的就是使用一種技術來爲命令傳播「購買時間」。

例如,假設我們在列表屏幕上,用戶可以在其中執行各種操作,其中之一是將新項目添加到列表中。選擇添加項目後,您可以顯示「您想要接下來做什麼?」可能會有'添加另一個項目','執行此任務','執行其他任務','返回列表'。

當他們點擊一個選項時,數據可能已被刷新。

此外,如果您使用的是基於任務的用戶界面,你可以分析任務執行的模式,並利用這些「你會喜歡做下一個」屏幕來簡化UI。類似於亞馬遜的「其他人也購買了這些物品」。

1

如前所述,它是好的,以告訴請求命令)一直承認用戶(成功發行)。在一些失敗的情況下,系統應將此信息告知請求者,通過以下方式:

  • 電子郵件;
  • SMS;
  • 定製收件箱(例如,像SO收件箱);不管怎麼樣,我們都可以做到這一點。

例如,郵件客戶端/服務:

  • 我的郵件發送到錯誤的地址;
  • 郵件服務說:「電子郵件發送成功:)」
  • 幾分鐘後,我收到一個郵件從服務:「郵件無法送達」。

我相信告知用戶最近的失敗一個偉大的方式是提出了他的錯誤面板,而他的導航通過應用

enter image description here

+0

非常相似的觀點。謝謝 –

1

我不會欺騙用戶或犯其他一些動作阻止他去:用戶手勢可能以解散該警報等

例如需要。我希望在讀取方得到確認後,向UI傳輸數據。讓我們考慮這兩種情況:

  1. 用戶保存數據並且期望結果。連接建立朝向服務器。在被讀取方確認之後,它們將流向UI並且UI正在更新。

  2. 用戶保存數據並刷新網頁。重新加載後,數據將從數據存儲中獲取,並建立流連接。如果讀取方在此期間沒有更新數據存儲,則仍然存在打開的數據流,並且在數據到達讀取方後應該更新UI。

爲什麼從閱讀端流式傳輸,而不是直接從寫端傳輸?簡而言之,這將確認已經達到了讀取方。 從技術角度而言,可以使用Server-Sent Events

缺點:

結果仍然不會立即由讀出側反射。但至少在大多數情況下,用戶將能夠繼續他的工作而不被用戶界面阻擋。

1

我認爲其他答案混合在一起CQRS特別是在一般和最終一致性。基於任務的UI非常適合CQRS,但它不能解決最終一致的讀取模型的問題。

首先,我想挑戰你的說法:

用戶習慣點擊保存,並觀察結果瞬間......最終一致性這是不可能的。

該怎麼辦呢?爲什麼不能立即看到結果?我認爲這裏的問題是你的定義結果

任何操作的結果是已執行的動作。有很多方式來展示這一點!這取決於你想要完成什麼樣的動作。示例:

  • 發送電子郵件:如果用戶輸入了正確的電子郵件地址,則幾乎可以確保該操作將成功完成。爲了防止意外的故障,可以使用持久隊列,因爲這種操作不需要同步完成。所以你只是說「發送電子郵件」。通常情況下,當您要求重置密碼時,您會看到這種迴應。

  • 更新用戶配置文件中的一些信息:在客戶端驗證了新數據後,很可能命令也會成功,因爲可能發生的唯一情況是數據庫錯誤(如果使用數據庫)。同樣,即使這可以通過使用持久隊列來緩解。在這種情況下,您只需以相同的格式顯示更新的字段。 SPA的良好做法是在客戶端提供全面的數據存儲,就像Redux一樣。在這種情況下,您可以通過發送命令並更新客戶端存儲來安全地更新服務器,這將導致UI顯示最新數據。 免責聲明:一些答案稱這種技術爲「欺騙用戶」,但我不同意這個定義。

  • 如果您的命令容易出錯,您可以使用Websockets或Server端事件等其他答案中已經描述的技術來傳回錯誤。這需要相當多的額外工作。您也可以發送命令並等待回覆或同步執行命令。有人會說「這不是CQRS」,但這只是另一個受到挑戰的教條。確保命令已經結束前一點(客戶端數據存儲)完成執行將是一個很好的解決方案。

我不確定是否有任何100%防彈技術可以讓您始終顯示讀取模型中的非陳舊數據。我認爲這違背了CQRS的原則。即使對於實時事件,您也只會獲得指示您寫入模型已更新的事件。儘管如此,你的預測可能會失敗,對此的反應是另一回事。

不過,我不會集中在這個問題上那麼多。事實是,經過良好測試的預測和幾乎保證的命令將非常有效。對於90%的情況下的錯誤處理,只需手動或半手動過程即可從這些錯誤中恢復。對於最後的10%,您可以將來自服務器的一般性「錯誤」消息合併爲「對不起,您的操作XXX未能執行」,而最重要的操作可能會有一些創意過程,但實際上這些情況會非常非常罕見。

+0

有趣的觀點。由於項目已經關閉很久,我幾乎無法爲您的建議製作原型,但無論如何都要感謝 –