恢复过期副本
在应用变更之前,Sync Framework 将源副本的遗忘知识与目标副本的当前知识进行比较。如果目标知识不包含遗忘知识,Sync Framework 将目标副本识别为已过期并开始恢复同步。
为执行恢复同步,Sync Framework 采取以下步骤:
如果应用程序已注册以接收通知,Sync Framework 将向应用程序通知需要执行恢复同步。应用程序可以选择完全枚举源副本中的所有项、执行部分同步或取消同步。默认操作为取消同步。
当应用程序指定完全枚举时,Sync Framework 放弃当前变更批,完全枚举源副本中的所有项,并将它们应用于目标副本。
当应用程序指定部分同步时,Sync Framework 继续枚举源变更,并像在典型同步中一样将它们应用于目标副本,而将对已知知识的变更作为单个项异常进行应用。
了解恢复同步
在 Sync Framework 同步社区中,每个副本都包含有关该副本中的项的元数据。元数据跟踪与副本中存储的项的创建、修改和删除有关的信息。通常,副本必须定期清除已删除项的元数据,以避免耗尽存储空间。当副本已删除某个已删除项的元数据时,在同步过程中,它不再能够枚举此删除,而将其作为一项变更发送。只要同步社区中的所有副本在清除元数据之前同步删除,就会正确地传播所有删除而不会出现问题。
然而,如果某个副本在另一份副本已执行元数据清除之后尚未同步其数据,则前者将成为过期副本。在这种情况下,已执行清除的副本不再能够枚举已清除的变更,因此无法将这些变更发送到过期副本。为从这一问题中恢复,当在已执行元数据清除的源副本与过期的目标副本之间尝试执行同步时,Sync Framework 要求使用恢复同步来还原目标副本。之所以要求恢复同步,目的是为了防止过期副本重新引入已从同步社区中删除的项。
Sync Framework 使用源副本的遗忘知识来检测目标副本何时过期。当某一副本删除某个已删除项的元数据时,它在该副本的遗忘知识中记录此删除的版本。然后,可以使用遗忘知识来确定副本已知的项、已删除的项和已删除其元数据的项。请注意,遗忘知识是对已删除其元数据的项数的过高估计。因此,遗忘知识可能还包含在元数据中仍然具有活动条目的项。
响应恢复同步的通知
应用程序可以进行注册,以接收需要恢复同步的通知。此通知向应用程序提供开始完全枚举、继续当前会话或停止会话的机会。默认情况下,如果应用程序尚未注册以接收此通知,Sync Framework 将停止会话。
使用托管代码响应恢复同步的通知
为了接收需要恢复同步的通知,应用程序实现一个事件处理程序并注册它以接收 FullEnumerationNeeded 事件。当引发此事件时,此事件处理程序通过将 FullEnumerationNeededEventArgs 对象的 Action 属性设置为以下操作之一来进行响应:
Full 导致 Sync Framework 放弃当前变更批,并通过调用以下方法来开始完全枚举:
调用 GetFullEnumerationChangeBatch 方法以枚举源副本中的所有项变更。
调用 ProcessFullEnumerationChangeBatch 方法以将变更应用于目标副本。
Partial 导致 Sync Framework 与在典型同步中一样应用当前变更批和继续会话,只是将对已知知识的所有变更作为单个项例外进行应用。由于单个项例外比典型的知识表示形式效率低,因此仅在不能立即执行完全枚举时才使用部分同步。请注意 Sync Framework 将继续在每个同步的开始请求完全枚举,直到执行完全枚举。
Abort 导致 Sync Framework 停止当前会话。
使用非托管代码响应恢复同步的通知
为了接收需要恢复同步的通知,应用程序实现 ISyncCallback 接口并通过使用 ISyncSession::RegisterCallback 来注册此接口。在开始恢复同步之前,Sync Framework 调用 ISyncCallback::OnFullEnumerationNeeded。此方法返回以下操作之一:
SFEA_FULL_ENUMERATION 导致 Sync Framework 放弃当前变更批,并通过调用以下方法来开始完全枚举:
调用 IKnowledgeSyncProvider::GetFullEnumerationChangeBatch 方法以枚举源副本中的所有项变更。
调用 IKnowledgeSyncProvider::ProcessFullEnumerationChangeBatch 方法以将变更应用于目标副本。
SFEA_PARTIAL_SYNC 导致 Sync Framework 与在典型同步中一样应用当前变更批和继续会话,只是将对已知知识的所有变更作为单个项例外进行应用。由于单个项例外比典型的知识表示形式效率低,因此仅在不能立即执行完全枚举时才使用部分同步。请注意 Sync Framework 将继续在每个同步的开始请求完全枚举,直到执行完全枚举。
SFEA_ABORT 导致 Sync Framework 停止当前会话。
完全枚举源副本中的所有变更
在完全枚举过程中,Sync Framework 要求源提供程序枚举其所有变更。然后,Sync Framework 将源提供程序中的变更与目标副本中的项进行比较。对于目标副本中的任何项,如果它在源提供程序中不具备对应的变更,则该项将被视为已从源副本中删除并将从目标副本中删除。因此,请确保源提供程序正确地枚举源副本中的所有项,否则将从目标副本中错误地删除项。
使用托管代码完全枚举变更
为了从源提供程序完全枚举变更,Sync Framework 调用 GetFullEnumerationChangeBatch,而不调用 GetChangeBatch。调用此方法时,源提供程序返回 FullEnumerationChangeBatch 对象。若要生成此变更批,请执行以下步骤:
通过使用 BeginOrderedGroup 打开一个排序组。用于开始该组的项 ID 必须为所枚举的第一个 ID,且必须小于或等于在 GetFullEnumerationChangeBatch 中指定的枚举下限。
可以选择向批中添加变更,这些变更按项 ID 排序、所具有的项 ID 小于枚举下限且未包含在目标知识中。
向批中添加变更,这些变更按项 ID 排序且所具有的项 ID 大于或等于枚举下限。
通过使用 EndOrderedGroup 关闭此排序组。将枚举上限指定为添加到该组的最后一个变更的 ID。当此批为最后一个批时,将枚举上限指定为 Infinity。
当此批为最后一个批时,调用 SetLastBatch;;否则,Sync Framework 将再次调用 GetFullEnumerationChangeBatch。
使用非托管代码完全枚举变更
为了从源提供程序完全枚举变更,Sync Framework 调用 IKnowledgeSyncProvider::GetFullEnumerationChangeBatch,而不调用 IKnowledgeSyncProvider::GetChangeBatch。调用此方法时,源提供程序返回 ISyncFullEnumerationChangeBatch 对象。若要生成此变更批,请执行以下步骤:
通过使用 IProviderSyncServices::CreateFullEnumerationChangeBatch 创建变更批对象。
通过使用 ISyncChangeBatchBase::BeginOrderedGroup 打开一个排序组。用于开始该组的项 ID 必须为所枚举的第一个 ID,且必须小于或等于在 GetFullEnumerationChangeBatch 中指定的枚举下限。
可以选择向批中添加变更,这些变更按项 ID 排序、所具有的项 ID 小于枚举下限且未包含在目标知识中。
向批中添加变更,这些变更按项 ID 排序且所具有的项 ID 大于或等于枚举下限。
通过使用 ISyncChangeBatchBase::EndOrderedGroup 关闭此排序组。将枚举上限指定为添加到该组的最后一个变更的 ID。当此批为最后一个批时,将枚举上限指定为 NULL。
当此批为最后一个批时,调用 ISyncChangeBatchBase::SetLastBatch;否则,Sync Framework 将再次调用 GetFullEnumerationChangeBatch。
在恢复同步期间处理变更
为了确定要从源副本中删除哪些项,Sync Framework 要求目标提供程序以项 ID 的排序顺序,枚举目标副本中其项 ID 介于每个变更批的枚举下限与枚举上限之间的所有项。对于目标副本中的某个项,如果未从源提供程序中枚举对应的变更,则将删除此项。
目标提供程序将目标项的这一列表传递给变更应用方。变更应用方确定如何处理每个变更,并调用适当的目标提供程序方法将此变更应用于目标副本。
使用托管代码处理变更
为了在恢复同步期间处理变更,Sync Framework 调用目标提供程序的 ProcessFullEnumerationChangeBatch 方法。此方法提供 FullEnumerationChangeBatch 对象,该对象包含源提供程序中的变更。
如果目标提供程序使用由 Sync Framework 提供的 NotifyingChangeApplier 对象,则目标提供程序必须调用 ApplyFullEnumerationChanges 方法以应用这些变更。此方法要求其项 ID 介于源变更批的 DestinationVersionEnumerationRangeLowerBound 与 DestinationVersionEnumerationRangeUpperBound 属性之间的所有目标变更的集合(按项 ID 排序)。若要应用变更,NotifyingChangeApplier 对象将与典型同步一样调用 INotifyingChangeApplierTarget 方法。
使用非托管代码处理变更
为了在恢复同步期间处理变更,Sync Framework 调用目标提供程序的 IKnowledgeSyncProvider::ProcessFullEnumerationChangeBatch 方法。此方法提供 ISyncFullEnumerationChangeBatch 对象,该对象包含源提供程序中的变更。
如果目标提供程序使用由 Sync Framework 提供的 ISynchronousNotifyingChangeApplier 对象,则目标提供程序必须调用 ISynchronousNotifyingChangeApplier::ApplyFullEnumerationChanges 方法以应用变更。此方法要求其项 ID 介于源变更批的 ISyncFullEnumerationChangeBatch::GetClosedLowerBoundItemId 与 ISyncFullEnumerationChangeBatch::GetClosedUpperBoundItemId 属性之间的所有目标变更的集合(按项 ID 排序)。若要应用变更,ISynchronousNotifyingChangeApplier 对象将与典型同步一样调用 ISynchronousNotifyingChangeApplierTarget 接口 方法。