// <summary> /// Initializes a server that has never synchronized before. /// </summary> /// <remarks> /// Thread safety: this is NOT thread safe. Because it is NOT meant to run multi-threaded. /// Callers MUST ensure thread-safety. /// </remarks> private SyncBootState InitializeColdBootState() { lock (_locko) { if (_cancellationToken.IsCancellationRequested) { return(SyncBootState.Unknown); } SyncBootState syncState = _syncBootStateAccessor.GetSyncBootState(); if (syncState == SyncBootState.ColdBoot) { // Get the last id in the db and store it. // Note: Do it BEFORE initializing otherwise some instructions might get lost // when doing it before. Some instructions might run twice but this is not an issue. var maxId = CacheInstructionService.GetMaxInstructionId(); // if there is a max currently, or if we've never synced if (maxId > 0 || _lastSyncedFileManager.LastSyncedId < 0) { _lastSyncedFileManager.SaveLastSyncedId(maxId); } } return(syncState); } }
private void CreateAndDeliveryMultipleInstructions(CacheInstructionService sut) { for (int i = 0; i < 3; i++) { List <RefreshInstruction> instructions = CreateInstructions(); sut.DeliverInstructions(instructions, i == 2 ? LocalIdentity : AlternateIdentity); } }
/// <inheritdoc/> public override void SendMessages() { ICollection <RefreshInstructionEnvelope> batch = GetBatch(false); if (batch == null) { return; } RefreshInstruction[] instructions = batch.SelectMany(x => x.Instructions).ToArray(); batch.Clear(); CacheInstructionService.DeliverInstructionsInBatches(instructions, LocalIdentity); }
protected override void DeliverRemote( ICacheRefresher refresher, MessageType messageType, IEnumerable <object> ids = null, string json = null) { var idsA = ids?.ToArray(); if (GetArrayType(idsA, out Type idType) == false) { throw new ArgumentException("All items must be of the same type, either int or Guid.", nameof(ids)); } IEnumerable <RefreshInstruction> instructions = RefreshInstruction.GetInstructions(refresher, JsonSerializer, messageType, idsA, idType, json); CacheInstructionService.DeliverInstructions(instructions, LocalIdentity); }
private void BatchMessage( ICacheRefresher refresher, MessageType messageType, IEnumerable <object> ids = null, Type idType = null, string json = null) { ICollection <RefreshInstructionEnvelope> batch = GetBatch(true); IEnumerable <RefreshInstruction> instructions = RefreshInstruction.GetInstructions(refresher, JsonSerializer, messageType, ids, idType, json); // Batch if we can, else write to DB immediately. if (batch == null) { CacheInstructionService.DeliverInstructionsInBatches(instructions, LocalIdentity); } else { batch.Add(new RefreshInstructionEnvelope(refresher, instructions)); } }
/// <summary> /// Synchronize the server (throttled). /// </summary> public override void Sync() { if (!EnsureInitialized()) { return; } lock (_locko) { if (_syncing) { return; } // Don't continue if we are released if (_cancellationToken.IsCancellationRequested) { return; } if ((DateTime.UtcNow - _lastSync) <= GlobalSettings.DatabaseServerMessenger.TimeBetweenSyncOperations) { return; } // Set our flag and the lock to be in it's original state (i.e. it can be awaited) _syncing = true; _syncIdle.Reset(); _lastSync = DateTime.UtcNow; } try { ProcessInstructionsResult result = CacheInstructionService.ProcessInstructions( _cacheRefreshers, _serverRoleAccessor.CurrentServerRole, _cancellationToken, LocalIdentity, _lastPruned, _lastSyncedFileManager.LastSyncedId); if (result.InstructionsWerePruned) { _lastPruned = _lastSync; } if (result.LastId > 0) { _lastSyncedFileManager.SaveLastSyncedId(result.LastId); } } finally { lock (_locko) { // We must reset our flag and signal any waiting locks _syncing = false; } _syncIdle.Set(); } }