private void NotifyLocked(IEnumerable <MediaCacheRefresher.JsonPayload> payloads, out bool anythingChanged) { anythingChanged = false; // locks: // see notes for content cache refresher foreach (var payload in payloads) { _logger.LogDebug("Notified {ChangeTypes} for media {MediaId}", payload.ChangeTypes, payload.Id); if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) { using (var scope = _scopeProvider.CreateScope()) { scope.ReadLock(Constants.Locks.MediaTree); LoadMediaFromDatabaseLocked(false); scope.Complete(); } anythingChanged = true; continue; } if (payload.ChangeTypes.HasType(TreeChangeTypes.Remove)) { if (_mediaStore.ClearLocked(payload.Id)) { anythingChanged = true; } continue; } if (payload.ChangeTypes.HasTypesNone(TreeChangeTypes.RefreshNode | TreeChangeTypes.RefreshBranch)) { // ?! continue; } // TODO: should we do some RV checks here? (later) var capture = payload; using (var scope = _scopeProvider.CreateScope()) { scope.ReadLock(Constants.Locks.MediaTree); if (capture.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch)) { // ?? should we do some RV check here? // IMPORTANT GetbranchContentSources sorts kits by level and by sort order var kits = _publishedContentService.GetBranchMediaSources(capture.Id); _mediaStore.SetBranchLocked(capture.Id, kits); } else { // ?? should we do some RV check here? var kit = _publishedContentService.GetMediaSource(capture.Id); if (kit.IsEmpty) { _mediaStore.ClearLocked(capture.Id); } else { _mediaStore.SetLocked(kit); } } scope.Complete(); } // ?? cannot tell really because we're not doing RV checks anythingChanged = true; } }
// Calling this method means we have a lock on the contentStore (i.e. GetScopedWriteLock) private void NotifyLocked(IEnumerable <ContentCacheRefresher.JsonPayload> payloads, out bool draftChanged, out bool publishedChanged) { publishedChanged = false; draftChanged = false; // locks: // content (and content types) are read-locked while reading content // contentStore is wlocked (so readable, only no new views) // and it can be wlocked by 1 thread only at a time // contentStore is write-locked during changes - see note above, calls to this method are wrapped in contentStore.GetScopedWriteLock foreach (var payload in payloads) { _logger.LogDebug("Notified {ChangeTypes} for content {ContentId}", payload.ChangeTypes, payload.Id); if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) { using (var scope = _scopeProvider.CreateScope()) { scope.ReadLock(Constants.Locks.ContentTree); LoadContentFromDatabaseLocked(false); scope.Complete(); } draftChanged = publishedChanged = true; continue; } if (payload.ChangeTypes.HasType(TreeChangeTypes.Remove)) { if (_contentStore.ClearLocked(payload.Id)) { draftChanged = publishedChanged = true; } continue; } if (payload.ChangeTypes.HasTypesNone(TreeChangeTypes.RefreshNode | TreeChangeTypes.RefreshBranch)) { // ?! continue; } // TODO: should we do some RV check here? (later) var capture = payload; using (var scope = _scopeProvider.CreateScope()) { scope.ReadLock(Constants.Locks.ContentTree); if (capture.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch)) { // ?? should we do some RV check here? // IMPORTANT GetbranchContentSources sorts kits by level and by sort order var kits = _publishedContentService.GetBranchContentSources(capture.Id); _contentStore.SetBranchLocked(capture.Id, kits); } else { // ?? should we do some RV check here? var kit = _publishedContentService.GetContentSource(capture.Id); if (kit.IsEmpty) { _contentStore.ClearLocked(capture.Id); } else { _contentStore.SetLocked(kit); } } scope.Complete(); } // ?? cannot tell really because we're not doing RV checks draftChanged = publishedChanged = true; } }