예제 #1
0
 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);
     }
 }
예제 #2
0
파일: MetaFile.cs 프로젝트: DmT021/Urfunet
        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();
                }
            }
        }
예제 #3
0
 protected FsObjectOperationMessage(BaseFile srcFile)
 {
     this.srcFile = srcFile;
 }
예제 #4
0
 public UpdateMetaInfoMessage(BaseFile srcFile)
     : base(srcFile)
 {
 }
예제 #5
0
 public NewFileMessage(BaseFile srcFile)
 {
     this.srcFile = srcFile;
 }
예제 #6
0
 void synchfiles(BaseFile srcFile, FSObjectEvents eventtype)
 {
     Dispatcher.BeginInvoke(new Action(() =>
     {
         v_curdir = v_curdir;
     }), null);
 }
예제 #7
0
 public DownloadFileMessage(BaseFile baseFile, EventWaitHandle m)
     : base(baseFile)
 {
     if (m != null && !WaitHandles.ContainsKey(srcFile.RelativePath))
         WaitHandles.Add(srcFile.RelativePath, m);
 }
예제 #8
0
        /// <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;
            }
        }
예제 #9
0
파일: Client.cs 프로젝트: DmT021/Urfunet
        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));

            }
        }
예제 #10
0
파일: Client.cs 프로젝트: DmT021/Urfunet
 internal INode GetFileOwner(BaseFile baseFile)
 {
     lock (RemoteClients)
     {
         var own = RemoteClients.FirstOrDefault(x => x.Id.ToString() == baseFile.meta.Owner);
         return own;
     }
 }
예제 #11
0
파일: Client.cs 프로젝트: DmT021/Urfunet
        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 =\
                }
            }
        }
예제 #12
0
파일: Client.cs 프로젝트: DmT021/Urfunet
 /// <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;
 }
예제 #13
0
        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);
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
 public SendFileMessage(BaseFile baseFile,string specdir)
     : base(baseFile)
 {
     this.specdir = specdir;
 }
예제 #16
0
 public LockFileMessage(BaseFile srcFile)
     : base(srcFile)
 {
 }
예제 #17
0
파일: File.cs 프로젝트: DmT021/Urfunet
 public FileData(BaseFile f)
 {
     this.ParentFile = f;
 }