/// <summary> /// Checks if any of the neighbors expired. /// If so, it starts the process of their removal. /// </summary> public async Task CheckExpiredNeighborsAsync() { log.Trace("()"); // If a neighbor server's LastRefreshTime is lower than this limit, it is expired. DateTime limitLastRefreshTime = DateTime.UtcNow.AddSeconds(-Config.Configuration.NeighborExpirationTimeSeconds); using (UnitOfWork unitOfWork = new UnitOfWork()) { bool success = false; DatabaseLock[] lockObjects = new DatabaseLock[] { UnitOfWork.NeighborLock, UnitOfWork.NeighborhoodActionLock }; using (IDbContextTransaction transaction = await unitOfWork.BeginTransactionWithLockAsync(lockObjects)) { try { List <Neighbor> expiredNeighbors = (await unitOfWork.NeighborRepository.GetAsync(n => n.LastRefreshTime < limitLastRefreshTime, null, true)).ToList(); if (expiredNeighbors.Count > 0) { log.Debug("There are {0} expired neighbors.", expiredNeighbors.Count); foreach (Neighbor neighbor in expiredNeighbors) { // This action will cause our proximity server to erase all activities of the neighbor that has been removed. NeighborhoodAction action = new NeighborhoodAction() { ServerId = neighbor.NeighborId, Timestamp = DateTime.UtcNow, Type = NeighborhoodActionType.RemoveNeighbor, TargetActivityId = null, TargetActivityOwnerId = null, AdditionalData = null }; await unitOfWork.NeighborhoodActionRepository.InsertAsync(action); } await unitOfWork.SaveThrowAsync(); transaction.Commit(); } else { log.Debug("No expired neighbors found."); } success = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!success) { log.Warn("Rolling back transaction."); unitOfWork.SafeTransactionRollback(transaction); } unitOfWork.ReleaseLock(lockObjects); } } log.Trace("(-)"); }
/// <summary> /// Checks if any of the neighbors expired. /// If so, it starts the process of their removal. /// </summary> public async Task CheckExpiredNeighborsAsync() { log.Trace("()"); // If a neighbor server's LastRefreshTime is lower than this limit, it is expired. DateTime limitLastRefreshTime = DateTime.UtcNow.AddSeconds(-Config.Configuration.NeighborExpirationTimeSeconds); List <byte[]> neighborsToDeleteIds = new List <byte[]>(); using (UnitOfWork unitOfWork = new UnitOfWork()) { bool success = false; DatabaseLock[] lockObjects = new DatabaseLock[] { UnitOfWork.NeighborLock, UnitOfWork.NeighborhoodActionLock }; using (IDbContextTransaction transaction = await unitOfWork.BeginTransactionWithLockAsync(lockObjects)) { try { List <Neighbor> expiredNeighbors = (await unitOfWork.NeighborRepository.GetAsync(n => n.LastRefreshTime < limitLastRefreshTime, null, true)).ToList(); if (expiredNeighbors.Count > 0) { bool saveDb = false; log.Debug("There are {0} expired neighbors.", expiredNeighbors.Count); foreach (Neighbor neighbor in expiredNeighbors) { int unprocessedRemoveNeighborActions = await unitOfWork.NeighborhoodActionRepository.CountAsync(a => (a.ServerId == neighbor.NetworkId) && (a.Type == NeighborhoodActionType.RemoveNeighbor)); if (unprocessedRemoveNeighborActions == 0) { // This action will cause our proximity server to erase all profiles of the neighbor that has been removed. NeighborhoodAction action = new NeighborhoodAction() { ServerId = neighbor.NetworkId, Timestamp = DateTime.UtcNow, Type = NeighborhoodActionType.RemoveNeighbor, TargetActivityId = 0, TargetActivityOwnerId = null, AdditionalData = null }; await unitOfWork.NeighborhoodActionRepository.InsertAsync(action); saveDb = true; } else { log.Debug("There is an unprocessed RemoveNeighbor neighborhood action for neighbor ID '{0}'. Neighbor will be deleted.", neighbor.NetworkId.ToHex()); neighborsToDeleteIds.Add(neighbor.NetworkId); } } if (saveDb) { await unitOfWork.SaveThrowAsync(); transaction.Commit(); } } else { log.Debug("No expired neighbors found."); } success = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!success) { log.Warn("Rolling back transaction."); unitOfWork.SafeTransactionRollback(transaction); } unitOfWork.ReleaseLock(lockObjects); } if (neighborsToDeleteIds.Count > 0) { log.Debug("There are {0} neighbors to be deleted.", neighborsToDeleteIds.Count); foreach (byte[] neighborToDeleteId in neighborsToDeleteIds) { if (await unitOfWork.NeighborRepository.DeleteNeighborAsync(neighborToDeleteId)) { log.Debug("Neighbor ID '{0}' deleted.", neighborToDeleteId.ToHex()); } else { log.Warn("Unable to delete neighbor ID '{0}'.", neighborToDeleteId.ToHex()); } } } else { log.Debug("No neighbors to delete now."); } } log.Trace("(-)"); }