由于_push event, pull data_模型和多線程情況下,觀察者可能看不到數(shù)據(jù)全部的更新記錄(ps:因為總是獲取最新的數(shù)據(jù))。這是特意設(shè)計的: 因為大多數(shù)情況下(尤其更新app UI), 本來就只需要關(guān)心最新的數(shù)據(jù)。
然而, 如果客戶端(一般很少)想知道全部的變化歷史記錄, Agera 提供Repository
的子類型: Reservoir
,可以滿足這種場景。
Reservoir
是一個響應(yīng)版本隊列。數(shù)據(jù)可以通過Receiver
接口加入隊列,然后發(fā)起通知事件,然后觀察者可以從隊列中讀取數(shù)據(jù)(Repository.get()
)。
Reservoir
隊列的訪問是完全同步的,所以不會出現(xiàn)兩個客戶端從隊列中讀取到同一個數(shù)據(jù)(ps:就是線程安全)。
如果相同的值放入隊列多次,這也會認(rèn)為是不同的實例(ps:就是會生成多次通知事件)。
if the same value (the same Java object reference) is enqueued multiple times, they are different instances in the context of a reservoir).
返回數(shù)據(jù)類型是Result
, 所以如果客戶端嘗試從空隊列讀取數(shù)據(jù)的時候,可以接收Result.absent()
作為一個失敗的通知。
基于這種行為,Reservoir
非常適合必須處理事件源的每一個數(shù)據(jù)的響應(yīng)。
這種響應(yīng)可以使用[[compiled repository|Compiled-repositories]]實現(xiàn)。
如果合適的話,可以用Reservoir
作為事件源,使用.attemptGetFrom(reservoir).orSkip()
作為數(shù)據(jù)處理流程的開始指令。
一旦repository激活,Reservoir
中的觀察者模式就會建立好(ps:消費(fèi)者和生產(chǎn)者的模式)。
使用Reservoir
可以實現(xiàn)簡單的并行任務(wù),使用多個repository提供事件源和數(shù)據(jù)源,任務(wù)放入隊列,然后每個repository去執(zhí)行數(shù)據(jù)處理流程。
注意:為了做到并行執(zhí)行,repository都需要提交到線程池執(zhí)行或者運(yùn)行在不同的工作Looper(worker Loopers)。