/// <summary> /// Обмен схем репликации текущего узла с узлом storageHost. /// </summary> /// <param name="remoteNode">Удаленный узел хранилища.</param> /// <param name="currentReplicationSchema">Схема репликации текущего узла.</param> /// <returns></returns> public IReplicationSchema ExchangeSchema(IStorageNode remoteNode, IReplicationSchema currentReplicationSchema) { if (remoteNode == null) { throw new ArgumentNullException("remoteNode"); } if (currentReplicationSchema == null) { throw new ArgumentNullException("currentReplicationSchema"); } return(this.MakeRequest(x => { //схема репликации сети, известная текущему узлу WcfReplicationSchema typedCurrentReplicationSchema = new WcfReplicationSchema(currentReplicationSchema); WcfReplicationSchemaMessage exchangeMessage = new WcfReplicationSchemaMessage(typedCurrentReplicationSchema); //посылаем текущую схему узлу, к которому обращаемся //и получаем его схему с узла назначения WcfReplicationSchemaMessage remoteSchemaMessage = x.ExchangeSchema(exchangeMessage); return new WcfReplicationSchema(remoteSchemaMessage); }, remoteNode.Host)); }
public WcfReplicationSchema(IReplicationSchema replicationSchema) { if (replicationSchema == null) { throw new ArgumentNullException("replicationSchema"); } this.ReplicationSchema = replicationSchema; }
/// <summary> /// Обновляет знания о существующей схеме репликации. /// </summary> /// <param name="remoteSchema">Схема репликации узла, с которого пришел запрос.</param> public IReplicationSchema UpdateReplicationSchema(IReplicationSchema remoteSchema) { //обновление локальной схемы this.ReplicationObserver.UpdateSchema(remoteSchema); //возврат текущей схемы IReplicationSchema currentSchema = this.ReplicationObserver.GetCurrentSchema(); return(currentSchema); }
public WcfReplicationSchemaMessage ExchangeSchema(WcfReplicationSchemaMessage remoteSchemaMessage) { if (remoteSchemaMessage == null) { throw new ArgumentNullException("remoteSchemaMessage"); } WcfReplicationSchema remoteSchema = new WcfReplicationSchema(remoteSchemaMessage); IReplicationSchema currentSchema = this.ReplicationAdapter.UpdateReplicationSchema(remoteSchema); WcfReplicationSchema typedCurrentSchema = new WcfReplicationSchema(currentSchema); WcfReplicationSchemaMessage responseMessage = new WcfReplicationSchemaMessage(typedCurrentSchema); return(responseMessage); }
private void GetNeighborsWorker(object state) { if (state == null) { throw new ArgumentNullException("state"); } StorageNode node = (StorageNode)state; while (true) { try { //периодически запрашиваем информацию о сети //передаем текущие папки, которые реплицируются на данной ноде //чтобы возвращать только пересекающиеся IReplicationSchema currentSchema = this.GetCurrentSchema(); IReplicationSchema remoteSchema = this.ReplicationAdapter.Transport.ExchangeSchema(node, currentSchema); //обновляем схему по схеме соседнего узла по следующей логике //что пришло со строгой ссылкой, то всегда создаем (значит эта настройка соседнего узла) //со слабой ссылкой создаем только папки, по которым мы пересекаемся if (remoteSchema != null) { this.UpdateSchema(remoteSchema); } } catch (Exception ex) { this.Engine.Logger.WriteMessage(ex.ToString()); } finally { Thread.Sleep(Timeouts.Schema); } } }
private void UpdateSchemaItem(IReplicationSchema remoteSchema, IReplicationSchemaItem remoteSchemaItem) { if (remoteSchema == null) { throw new ArgumentNullException("remoteSchema"); } if (remoteSchemaItem == null) { throw new ArgumentNullException("remoteSchemaItem"); } bool forCurrentStorage = remoteSchemaItem.StorageID == this.Engine.CurrentNode.UniqueID; bool isStrongRelation = remoteSchemaItem.RelationType == ReplicationRelation.Strong; //хост хранилища может поменяться //ищем по UniqueID и если не совпадают хосты, то меняем хост //доверяем хосту, только от которого пришел ответ if (forCurrentStorage) { if (isStrongRelation) { //есть строгая ссылка на текущий узел, для узла, с которого пришел запрос. #region Обновление информации об узле bool justCreated; StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated); if (!justCreated) { //если узел уже был, то проверяем нужно ли обновить хост существующего узла if (remoteNode.Host.ToLower() != remoteSchema.Host.ToLower()) { lock (_updateStorageLocker) { if (remoteNode.Host.ToLower() != remoteSchema.Host.ToLower()) { remoteNode.Host = remoteSchema.Host.ToLower(); remoteNode.Update(); } } } } #endregion } } //если это STRONG признак, то создаем, если настройки нет foreach (string folderUrl in remoteSchemaItem.Folders) { if (isStrongRelation) { #region strong relation //настройка пришла непосредственно с узла схемы и на этом узле есть //если она предназначена для текущего узла, то создаем/снимаем признак удаленности if (forCurrentStorage) { //узел remote схемы bool justCreated; StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated); //получаем папку для репликации с remote узлом bool replicationFolderJustCreated; ReplicationFolder replicationFolder = this.EnsureReplicationFolder(remoteNode, folderUrl, false, out replicationFolderJustCreated); if (!replicationFolderJustCreated) { //если настройка существовала и была удалена, то восстанавливаем ее if (replicationFolder.Deleted) { replicationFolder.Deleted = false; replicationFolder.Update(); } } } else { //Strong ссылка на репликацию с 3-им (отличным от текущего) узлом, //смотрим если на текущем узле есть пересекающиеся папки, то добавляем weak настройку this.AddWeakRelation(remoteSchemaItem.StorageID, remoteSchemaItem.Name, folderUrl); } #endregion } else { if (forCurrentStorage) { //слабые ссылки на самого себя не надо восстанавливать continue; } //если это WEAK признак, то создаем, только если есть пересекающиеся настройки this.AddWeakRelation(remoteSchemaItem.StorageID, remoteSchemaItem.Name, folderUrl); //проверку на признак удаления делать не нужно, т.к. ссылка слабая } } }
/// <summary> /// Обновляет текущую схему репликацию сети, по схеме репликации другого узла сети. /// </summary> /// <param name="remoteSchema">Схема репликации другого узла сети.</param> internal void UpdateSchema(IReplicationSchema remoteSchema) { if (remoteSchema == null) { throw new ArgumentNullException("remoteSchema"); } //remote схема содержит ссылки на текущий узел bool remoteSchemaContainsCurrentStorage = false; //обновляем схему по схеме соседнего узла по следующей логике //что пришло со строгой ссылкой, то всегда создаем (значит эта настройка соседнего узла) //со слабой ссылкой создаем только папки, по которым мы пересекаемся if (remoteSchema.StrongItems != null) { foreach (IReplicationSchemaItem schemaItem in remoteSchema.StrongItems) { bool forCurrentStorage = schemaItem.StorageID == this.Engine.CurrentNode.UniqueID; if (!remoteSchemaContainsCurrentStorage) { remoteSchemaContainsCurrentStorage = forCurrentStorage; } this.UpdateSchemaItem(remoteSchema, schemaItem); } } if (remoteSchema.WeakItems != null) { foreach (IReplicationSchemaItem schemaItem in remoteSchema.WeakItems) { bool forCurrentStorage = schemaItem.StorageID == this.Engine.CurrentNode.UniqueID; if (!remoteSchemaContainsCurrentStorage) { remoteSchemaContainsCurrentStorage = forCurrentStorage; } this.UpdateSchemaItem(remoteSchema, schemaItem); } } if (remoteSchemaContainsCurrentStorage) { //схема remote узла содержит текущий узел bool justCreated; StorageNode remoteNode = this.EnsureNode(remoteSchema.StorageID, remoteSchema.Host, out justCreated); remoteNode.LastAccessTime = DateTime.Now; remoteNode.Update(); } //удаление текущий настроек по remote схеме //для этого нужно пройтись по всем настройкам схемы текущего узла для remote узла if (_replicationFolders.ContainsKey(remoteSchema.StorageID)) { #region Удаление из текущей схемы Dictionary <string, ReplicationFolder> replicationFoldersForRemoteSchema = _replicationFolders[remoteSchema.StorageID]; foreach (ReplicationFolder replicationFolder in replicationFoldersForRemoteSchema.Values) { if (replicationFolder.IsCurrentNodeSettings) { //в схеме текущего узла репликация с remote узлом задана в настройке (STRONG) //такие настройки удалять не нужно continue; } bool containsInRemoteSchema = false; FolderUri localUri = new FolderUri(replicationFolder.Folder.Url); //содержаться может и в STRONG и в WEAK виде if (remoteSchema.StrongItems != null) { foreach (IReplicationSchemaItem schemaItem in remoteSchema.StrongItems) { if (schemaItem.Folders != null) { foreach (string folderUrl in schemaItem.Folders) { FolderUri remoteUri = new FolderUri(folderUrl); if (localUri.UrlLower == remoteUri.UrlLower) { containsInRemoteSchema = true; break; } } } if (containsInRemoteSchema) { break; } } } if (!containsInRemoteSchema && remoteSchema.WeakItems != null) { foreach (IReplicationSchemaItem schemaItem in remoteSchema.WeakItems) { if (schemaItem.Folders != null) { foreach (string folderUrl in schemaItem.Folders) { FolderUri remoteUri = new FolderUri(folderUrl); if (localUri.UrlLower == remoteUri.UrlLower) { containsInRemoteSchema = true; break; } } } if (containsInRemoteSchema) { break; } } } //в remote схеме нет репликации с папками из схемы текущего узла if (!containsInRemoteSchema) { replicationFolder.Deleted = true; replicationFolder.Update(); } } #endregion } }