public override void OnRecived(RemoteClient from, Client to) { base.OnRecived(from, to); if (!string.IsNullOrEmpty(RelativePath)) srcFile = Environment.ParentClient.FileSystem.Find(RelativePath) as BaseFile; if (srcFile == null) { throw new Exception(string.Format("File {0} not fount (request from {1})", RelativePath, from.Id)); Environment.ParentClient.Log(LogLevel.Error, "File {0} not fount (request from {1})", RelativePath, from.Id); } }
public FileMetaInfo(BaseFile baseFile) { if (baseFile == null) throw new ArgumentNullException(); ParenFile = baseFile; //if metafile exists - read and return //else (if file exists) create metafile ,save metafile var metaexists =File.Exists(baseFile.MetaPath); var dataexists =File.Exists(baseFile.RealPath); Replics = new List<string>(); if (metaexists) { var tmp = JsonConvert.DeserializeObject<FileMetaInfo>(File.ReadAllText(ParenFile.MetaPath, Encoding.UTF8)); this.CreateDate = tmp.CreateDate; this.Hash = tmp.Hash; this.Id = tmp.Id; this.LastModifiedDate = tmp.LastModifiedDate; this.Name = tmp.Name; this.Owner = tmp.Owner; this.Replics = tmp.Replics; ParenFile = baseFile; } else { if (dataexists) { var strHashData = baseFile.data.ComputeHash(); Hash = strHashData; Id = Guid.NewGuid().ToString(); LastModifiedDate = DateTime.Now; CreateDate = DateTime.Now; Name = baseFile.Name; Save(); } } }
protected FsObjectOperationMessage(BaseFile srcFile) { this.srcFile = srcFile; }
public UpdateMetaInfoMessage(BaseFile srcFile) : base(srcFile) { }
public NewFileMessage(BaseFile srcFile) { this.srcFile = srcFile; }
void synchfiles(BaseFile srcFile, FSObjectEvents eventtype) { Dispatcher.BeginInvoke(new Action(() => { v_curdir = v_curdir; }), null); }
public DownloadFileMessage(BaseFile baseFile, EventWaitHandle m) : base(baseFile) { if (m != null && !WaitHandles.ContainsKey(srcFile.RelativePath)) WaitHandles.Add(srcFile.RelativePath, m); }
/// <summary> /// Add file by metafileinfo /// </summary> /// <param name="ParentFolder">Direactory to move new file</param> /// <param name="MetaFile">new file meta information</param> /// <returns></returns> public BaseFile AddFile(BaseFolder ParentFolder, FileMetaInfo MetaFile, FSObjectEvents FileEventType) { // if (ReadOnly) return null; lock (ParentFolder.FS) { var metapath = Path.Combine(ParentFolder.MetaPath, MetaFile.Name); if (File.Exists(metapath)) throw new Exception(string.Format("Файл \"{0}\" уже существует!", metapath));// return null; var f = new BaseFile(ParentFolder, MetaFile); ParentFolder.Files.Add(f); //add to files if (_OnFileEvent != null) _OnFileEvent(f, FileEventType); return f; } }
void FileSystem_OnFileEvent(BaseFile srcFile, FSObjectEvents eventtype) { lock (RemoteClients) { if (yNotRule.RulePool.ContainsKey(eventtype)) foreach (var r in yNotRule.RulePool[eventtype]) r.Eval(this, srcFile); } ///блокировки файлов и т д if (eventtype == FSObjectEvents.local_changed) { Log(LogLevel.Info, "Отправка обновленной метаинформации"); Environment.SendToAll(new UpdateMetaInfoMessage(srcFile)); } if (eventtype == FSObjectEvents.local_opend) { Environment.SendToAll(new LockFileMessage(srcFile)); if (!srcFile.data.Downloaded) { ///файл не загружен - выбираем слуйчайную реплику ///загружаем файл ///добавляем себя в реплики ///сообщаем об изменении метаинформации var r = GetRandomReplica(srcFile); if (r == null) throw new Exception("Не найдены релики"); var m = new EventWaitHandle(false, EventResetMode.AutoReset); (r as RemoteClient).Send(new DownloadFileMessage(srcFile, m)); m.WaitOne(-1); srcFile.AddReplica(Id); Log(NLog.LogLevel.Info, "Получена реплика файла {0}", this); FileSystem_OnFileEvent(srcFile, FSObjectEvents.local_changed); } } if (eventtype == FSObjectEvents.local_changed || eventtype == FSObjectEvents.remote_changed) { ///если хэши не совпадают (и реплика загружена), обновить реплику ///OR ///если я в репликах - я дожен загузить этот файл /// // if () if ((srcFile.data.Downloaded && srcFile.data.ComputeHash() != srcFile.meta.Hash) || (GetFileReplics(srcFile).Contains(this) && !srcFile.data.Downloaded)) { Log(LogLevel.Info, "Файл изменен. Инициирую обновление {0}", srcFile); var m = new EventWaitHandle(false, EventResetMode.AutoReset); Log(LogLevel.Info, "Загружаю реплику {0}", srcFile.Name); (GetFileOwner(srcFile) as RemoteClient).Send(new DownloadFileMessage(srcFile, m)); //m.WaitOne(-1); } Log(LogLevel.Info, "Обновлена метаинформация для файла {0}", srcFile.Name); } if (eventtype == FSObjectEvents.local_closed) { ///сравнить хэш ///если совпадает - файл не изменен. просто разлокируем его ///если нет - ставим себя влядельцем файла и рассылаем всем новую метаинфу. ///те должны сравнить хэш и загрузить файл. ///после этого файл можно разблокировать /// var oldhash = srcFile.meta.Hash; var newhash = srcFile.data.ComputeHash(); if (oldhash != newhash) { srcFile.SetHash(newhash); srcFile.SetOwner(Id); FileSystem_OnFileEvent(srcFile, FSObjectEvents.local_changed); // ParentFolder.FS.ParentClient.Environment.SendToAll(new UpdateMetaInfoMessage(this)); } Environment.SendToAll(new UnLockFileMessage(srcFile)); } }
internal INode GetFileOwner(BaseFile baseFile) { lock (RemoteClients) { var own = RemoteClients.FirstOrDefault(x => x.Id.ToString() == baseFile.meta.Owner); return own; } }
public INode GetRandomReplica(BaseFile file) { lock (RemoteClients) { var reps = GetFileReplics(file); var rnd = new Random(DateTime.Now.Millisecond); while (true) { if (reps.Count == 0) return null; int ind = rnd.Next(reps.Count - 1); var res = reps[ind]; if (res.IsOnline) return res; reps.RemoveAt(ind); ///if no one alive - vary bad =\ } } }
/// <summary> /// return remote replica-nodes /// </summary> /// <param name="file"></param> /// <returns></returns> public List<INode> GetFileReplics(BaseFile file) { var res = new List<INode>(); lock (RemoteClients) { foreach (var it in file.meta.Replics) { var n = GetNodeById(it); if (n != null) res.Add(n); } } return res; }
private void LoadFS(BaseFolder RootDir) { lock (RootDir.FS) { foreach (var f in Directory.GetDirectories(RootDir.MetaPath)) { var d = new BaseFolder(RootDir, new DirectoryInfo(f).Name); RootDir.Folders.Add(d); } foreach (var f in Directory.GetFiles(RootDir.MetaPath)) { var newf = new BaseFile(RootDir, new FileInfo(f).Name); RootDir.Files.Add(newf); newf.OnFileEvent += OnFileEventHandled; } foreach (var f in RootDir.Folders) LoadFS(f); } }
public virtual void OnFileEventHandled(BaseFile srcFile, FSObjectEvents eventtype) { //if (ReadOnly && eventtype == FSObjectEvents.remote_create) // throw new Exception("Can not create file on readonly mode"); ///подписываемся на события каждого нового файла if (eventtype == FSObjectEvents.local_created || eventtype == FSObjectEvents.remote_create) srcFile.OnFileEvent += OnFileEventHandled; ///передача агрегированных событий if (OnFileEvent != null) OnFileEvent(srcFile, eventtype); }
public SendFileMessage(BaseFile baseFile,string specdir) : base(baseFile) { this.specdir = specdir; }
public LockFileMessage(BaseFile srcFile) : base(srcFile) { }
public FileData(BaseFile f) { this.ParentFile = f; }