Skip to content

Commit 12b65ab

Browse files
committed
adds some notes
1 parent 96ceae2 commit 12b65ab

File tree

1 file changed

+65
-49
lines changed

1 file changed

+65
-49
lines changed

src/Umbraco.Core/Sync/DatabaseServerMessenger.cs

Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ protected override void MessageSeversForIdsOrJson(IEnumerable<IServerAddress> se
8181
/// <returns></returns>
8282
protected override bool ShouldMakeDistributedCall(IEnumerable<IServerAddress> servers, ICacheRefresher refresher, MessageType dispatchType)
8383
{
84-
84+
8585
if (_initialized == false)
8686
{
8787
return false;
@@ -92,11 +92,11 @@ protected override bool ShouldMakeDistributedCall(IEnumerable<IServerAddress> se
9292
}
9393

9494
protected override void PerformDistributedCall(
95-
IEnumerable<IServerAddress> servers,
96-
ICacheRefresher refresher,
97-
MessageType dispatchType,
98-
IEnumerable<object> ids = null,
99-
Type idArrayType = null,
95+
IEnumerable<IServerAddress> servers,
96+
ICacheRefresher refresher,
97+
MessageType dispatchType,
98+
IEnumerable<object> ids = null,
99+
Type idArrayType = null,
100100
string jsonPayload = null)
101101
{
102102
var msg = new DistributedMessage
@@ -131,7 +131,7 @@ internal void FirstSync()
131131
// server and it will need to rebuild it's own persisted cache. Currently in that case it is Lucene and the xml
132132
// cache file.
133133
LogHelper.Warn<DatabaseServerMessenger>("No last synced Id found, this generally means this is a new server/install. The server will rebuild its caches and indexes and then adjust it's last synced id to the latest found in the database and will start maintaining cache updates based on that id");
134-
134+
135135
//perform rebuilds if specified
136136
if (_options.RebuildingCallbacks != null)
137137
{
@@ -140,8 +140,8 @@ internal void FirstSync()
140140
callback();
141141
}
142142
}
143-
144-
143+
144+
145145
//go get the last id in the db and store it
146146
var lastId = _appContext.DatabaseContext.Database.ExecuteScalar<int>(
147147
"SELECT MAX(id) FROM umbracoCacheInstruction");
@@ -174,53 +174,69 @@ internal void Sync()
174174

175175
using (DisposableTimer.DebugDuration<DatabaseServerMessenger>("Syncing from database..."))
176176
{
177-
//get the outstanding items
178-
179-
var sql = new Sql().Select("*")
180-
.From<CacheInstructionDto>()
181-
.Where<CacheInstructionDto>(dto => dto.Id > _lastId)
182-
.OrderBy<CacheInstructionDto>(dto => dto.Id);
183-
184-
var list = _appContext.DatabaseContext.Database.Fetch<CacheInstructionDto>(sql);
185-
186-
if (list.Count > 0)
187-
{
188-
189-
// TODO: Here we could ignore anything that originated from this server since it will already have processed that
190-
// change locally (see notes in DatabaseServerMessenger.MessageSeversForIdsOrJson ). However, depending on the sequence
191-
// of events, I think this server will still need to process it's own instructions from the database to ensure the correct
192-
// instruction's sequence order is processed.
193-
//
194-
// var toProcess = list.Where(x => x.OriginatedFrom != GetOriginatorValue());
195-
196-
foreach (var item in list)
197-
{
198-
try
199-
{
200-
var jsonArray = JsonConvert.DeserializeObject<JArray>(item.JsonInstruction);
201-
UpdateRefreshers(jsonArray);
202-
}
203-
catch (JsonException ex)
204-
{
205-
LogHelper.Error<DatabaseServerMessenger>("Could not deserialize a distributed cache instruction! Value: " + item.JsonInstruction, ex);
206-
}
207-
}
208-
209-
SaveLastSynced(list.Max(x => x.Id));
210-
}
177+
PerformSyncFromDb();
211178

212179
//prune old records
213-
_appContext.DatabaseContext.Database.Delete<CacheInstructionDto>("WHERE utcStamp < @pruneDate", new {pruneDate = DateTime.UtcNow.AddDays(_options.DaysToRetainInstructionRecords*-1)});
180+
_appContext.DatabaseContext.Database.Delete<CacheInstructionDto>("WHERE utcStamp < @pruneDate", new { pruneDate = DateTime.UtcNow.AddDays(_options.DaysToRetainInstructionRecords * -1) });
214181

215182
//reset
216183
_syncing = false;
217184
}
218-
219185
}
220186
}
221187
}
222188
}
223189

190+
/// <summary>
191+
/// This checks outstanding cache instructions from the db and processes them
192+
/// </summary>
193+
/// <remarks>
194+
/// This is not thread safe
195+
/// </remarks>
196+
private void PerformSyncFromDb()
197+
{
198+
//TODO: We 'could' recurse to ensure that no remaining instructions are pending in the table before proceeding but I don't think that
199+
// would be a good idea since instructions could keep getting added and then all other threads will probably get stuck from serving requests
200+
// (depending on what the cache refreshers are doing). I think it's best we do the one time check, process them and continue, if there are
201+
// pending requests after being processed, they'll just be processed on the next poll.
202+
203+
//get the outstanding items
204+
205+
var sql = new Sql().Select("*")
206+
.From<CacheInstructionDto>()
207+
.Where<CacheInstructionDto>(dto => dto.Id > _lastId)
208+
.OrderBy<CacheInstructionDto>(dto => dto.Id);
209+
210+
var list = _appContext.DatabaseContext.Database.Fetch<CacheInstructionDto>(sql);
211+
212+
if (list.Count > 0)
213+
{
214+
215+
// TODO: Here we could ignore anything that originated from this server since it will already have processed that
216+
// change locally (see notes in DatabaseServerMessenger.MessageSeversForIdsOrJson ). However, depending on the sequence
217+
// of events, I think this server will still need to process it's own instructions from the database to ensure the correct
218+
// instruction's sequence order is processed.
219+
//
220+
// var toProcess = list.Where(x => x.OriginatedFrom != GetOriginatorValue());
221+
222+
foreach (var item in list)
223+
{
224+
try
225+
{
226+
var jsonArray = JsonConvert.DeserializeObject<JArray>(item.JsonInstruction);
227+
UpdateRefreshers(jsonArray);
228+
}
229+
catch (JsonException ex)
230+
{
231+
LogHelper.Error<DatabaseServerMessenger>("Could not deserialize a distributed cache instruction! Value: " + item.JsonInstruction, ex);
232+
}
233+
}
234+
235+
SaveLastSynced(list.Max(x => x.Id));
236+
}
237+
}
238+
239+
224240
internal void UpdateRefreshers(JArray jsonArray)
225241
{
226242
foreach (var jsonItem in jsonArray)
@@ -287,7 +303,7 @@ internal void ReadLastSynced()
287303
/// <returns></returns>
288304
protected string GetOriginatorValue()
289305
{
290-
return JsonConvert.SerializeObject(new {machineName = NetworkHelper.MachineName, appDomainAppId = HttpRuntime.AppDomainAppId});
306+
return JsonConvert.SerializeObject(new { machineName = NetworkHelper.MachineName, appDomainAppId = HttpRuntime.AppDomainAppId });
291307
}
292308

293309
/// <summary>
@@ -309,7 +325,7 @@ private void SaveLastSynced(int id)
309325
File.WriteAllText(Path.Combine(tempFolder, HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty) + "-lastsynced.txt"), id.ToString(CultureInfo.InvariantCulture));
310326
}
311327

312-
328+
313329
#region Updates the refreshers
314330
private void RefreshAll(Guid uniqueIdentifier)
315331
{
@@ -355,7 +371,7 @@ private void RemoveById(Guid uniqueIdentifier, int Id)
355371
{
356372
var cr = CacheRefreshersResolver.Current.GetById(uniqueIdentifier);
357373
cr.Remove(Id);
358-
}
374+
}
359375
#endregion
360376

361377
/// <summary>
@@ -379,7 +395,7 @@ public void OnApplicationStarted(object sender, EventArgs eventArgs)
379395
{
380396
LogHelper.Warn<DatabaseServerMessenger>("The app is not configured or cannot connect to the database, this server cannot be initialized with " + typeof(DatabaseServerMessenger) + ", distributed calls will not be enabled for this server");
381397
}
382-
398+
383399
}
384400
}
385401
}

0 commit comments

Comments
 (0)