我想暴露一個可觀察的序列,給予觀察員數據庫表中的所有現有記錄加上任何未來的項目。爲了爭論,讓我們說它是日誌條目。因此,我有這樣的事情:如何種子從數據庫中觀察到
public class LogService
{
private readonly Subject<LogEntry> entries;
public LogService()
{
this.entries = new Subject<LogEntry>();
this.entries
.Buffer(...)
.Subscribe(async x => WriteLogEntriesToDatabaseAsync(x));
}
public IObservable<LogEntry> Entries
{
get { return this.entries; }
}
public IObservable<LogEntry> AllLogEntries
{
get
{
// how the heck?
}
}
public void Log(string message)
{
this.entries.OnNext(new LogEntry(message));
}
private async Task<IEnumerable<LogEntry>> GetLogEntriesAsync()
{
// reads existing entries from DB table and returns them
}
private async Task WriteLogEntriesToDatabaseAsync(IList<LogEntry> entries)
{
// writes entries to the database
}
}
我爲AllLogEntries
實施最初的想法是這樣的:
return Observable.Create<LogEntry>(
async observer =>
{
var existingEntries = await this.GetLogEntriesAsync();
foreach (var existingEntry in existingEntries)
{
observer.OnNext(existingEntry);
}
return this.entries.Subscribe(observer);
});
但這樣做的問題是,有可能記錄具有條目已被緩衝,尚未寫入數據庫。因此,這些條目將被錯過,因爲它們不在數據庫中,並且已經通過了可觀察的數據庫。
我的下一個念頭,就是緩衝的條目從非緩衝的分離和使用緩衝實現AllLogEntries
時:
return Observable.Create<LogEntry>(
async observer =>
{
var existingEntries = await this.GetLogEntriesAsync();
foreach (var existingEntry in existingEntries)
{
observer.OnNext(existingEntry);
}
return this.bufferedEntries
.SelectMany(x => x)
.Subscribe(observer);
});
有兩個問題:
- 這意味着客戶
AllLogEntries
也必須等待緩衝時間間隔才能通過,然後才能收到其日誌條目。我希望他們能夠即時查看日誌條目。 - 仍然存在競爭條件,即日誌條目可以寫入到我讀完現有日誌的點和我返回未來條目的點之間的數據庫中。
所以我的問題是:我將如何在這裏實現我的要求,不存在競爭條件的可能性,並避免任何主要的性能處罰?
如果你只是希望得到時新的記錄添加到上通知數據庫表,然後你可以看看這個答案。 http://stackoverflow.com/questions/15225147/watch-for-a-table-new-records-in-sql-database – bradgonesurfing
一些問題:日誌條目是否只發生在日誌服務的單個實例中?他們在保存之前是否有消除歧義的手段(即ID)?是否有序列號? –
@James:日誌服務是單身,是的。他們確實有一個數據庫生成的ID,但只有在保存後才知道。 –