MongoDB Change Events 可以被认为是独一无二的吗? [英] Can MongoDB Change Events be considered unique?
问题描述
说明
我正在利用 MongoDb 更改流(C# MongoDB.Driver v2.12.0)来跟踪单个集合的更改.在实验用例中,集合存储有关线程执行的信息.一个线程有两个属性:
状态
- 正在运行、已阻止或已完成BlockedCount
- 阻塞线程数
在执行期间,线程可以产生子线程并被阻塞,直到所有子线程都没有完成.每当子线程完成其执行时,它通过递减父线程的 BlockedCount
来更新数据库.一旦 BlockedCount
下降到 0,父线程应该继续执行.
订阅变更流的代码:
var pipeline = new EmptyPipelineDefinition>().Match(change => change.OperationType == ChangeStreamOperationType.Insert ||change.OperationType == ChangeStreamOperationType.Update ||change.OperationType == ChangeStreamOperationType.Replace).AppendStage、ChangeStreamDocument、ChangeStreamOutputWrapper("{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");var 选项 = 新的 ChangeStreamOptions{FullDocument = ChangeStreamFullDocumentOption.UpdateLookup};使用(var cursor = await coll.WatchAsync(管道,选项,取消令牌)){等待 cursor.ForEachAsync(异步更改 =>{//等待一些处理程序例程}, 取消令牌);}
问题
我注意到的是,即使更新操作完全相同,更改事件也可能不同.为了更好地解释这一点,这里有一个例子:有 1 个父线程和 3 个子线程完成它们的执行,观察到两种不同的行为:
父线程的 3 个不同的更新事件:
- 状态":BLOCKED",BlockedCount";:2
- 状态":BLOCKED",BlockedCount";: 1
- 状态":BLOCKED",BlockedCount";:0
父线程的 3 个相同的更新事件:
- 状态":BLOCKED",BlockedCount";:0
- 状态":BLOCKED",BlockedCount";:0
- 状态":BLOCKED",BlockedCount";:0
问题
- 这是否属于正常行为?
- 是否有某种配置可以防止这种情况发生,并且仅触发最新"更新?
是的,这是预期的行为.文档(link)指出:><块引用>
fullDocument
文档表示更新文档的最新多数提交版本.fullDocument
文档可能与更新操作时的文档不同,具体取决于更新操作和文档查找之间发生的交错多数提交操作的数量.
据我所知,没有办法克服或调整这种行为.但是,您可以做的是直接读取updateDescription
,手动跟踪更改.如果 BlockedCount
仅被设置(即,未删除并稍后重新添加),则不会很复杂.
Description
I am utilizing the MongoDb change stream (C# MongoDB.Driver v2.12.0) to track changes on a single collection. In an experimental use case the collection stores information about execution of threads.A thread has two properties:
Status
- RUNNING, BLOCKED or COMPLETEDBlockedCount
- number of blocking threads
During its execution, a thread can spawn children threads and be blocked until all of the children are not completed. Whenever a children thread completes its execution, it updates the database by decrementing the BlockedCount
of the parent. Once the BlockedCount
drops to 0, the parent thread should continue its execution.
Code for subscribing to change stream:
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<T>>()
.Match(change => change.OperationType == ChangeStreamOperationType.Insert ||
change.OperationType == ChangeStreamOperationType.Update ||
change.OperationType == ChangeStreamOperationType.Replace)
.AppendStage<ChangeStreamDocument<T>, ChangeStreamDocument<T>, ChangeStreamOutputWrapper<T>>(
"{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");
var options = new ChangeStreamOptions
{
FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
};
using (var cursor = await coll.WatchAsync(pipeline, options, cancellationToken))
{
await cursor.ForEachAsync(async change =>
{
// await some handler routine
}, cancellationToken);
}
Issue
What I have noticed is that the change events can be different even if the update operations are exactly the same. To better explain this, here is an example:There is 1 parent thread and 3 children threads completing their execution, there are two different behaviors observed:
3 distinct update events for the parent thread:
- "Status" : "BLOCKED", "BlockedCount" : 2
- "Status" : "BLOCKED", "BlockedCount" : 1
- "Status" : "BLOCKED", "BlockedCount" : 0
3 identical update events for the parent thread:
- "Status" : "BLOCKED", "BlockedCount" : 0
- "Status" : "BLOCKED", "BlockedCount" : 0
- "Status" : "BLOCKED", "BlockedCount" : 0
Questions
- Is this considered a normal behavior?
- Is there some kind of configuration that would prevent this, and fire only the 'latest' update?
Yes, that is the expected behavior. The documentation (link) states, that:
The
fullDocument
document represents the most current majority-committed version of the updated document. ThefullDocument
document may vary from the document at the time of the update operation depending on the number of interleaving majority-committed operations that occur between the update operation and the document lookup.
And as far as I know, there's no way to overcome nor adjust this behavior. However, what you can do, is to read updateDescription
directly, manually tracking the changes. It's not going to be complex if the BlockedCount
is only being set (i.e., not removed and re-added later).
这篇关于MongoDB Change Events 可以被认为是独一无二的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!