Fix for multiple processing of deep hierarchies
authorpkanavos <pkanavos@gmail.com>
Fri, 6 Jul 2012 15:25:35 +0000 (18:25 +0300)
committerpkanavos <pkanavos@gmail.com>
Fri, 6 Jul 2012 15:25:35 +0000 (18:25 +0300)
trunk/CommonAssemblyVersion.cs
trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/Agents/SelectiveUris.cs
trunk/Pithos.Core/PithosMonitor.cs

index 287e52c..33db52c 100644 (file)
@@ -46,7 +46,7 @@ using System.Reflection;
 // associated with an assembly.
 [assembly: AssemblyCompany("GRNET")]
 [assembly: AssemblyCopyright("Copyright © GRNet 2011-2012")]
-[assembly: AssemblyInformationalVersion("2012-07-05")]
+[assembly: AssemblyInformationalVersion("2012-07-06")]
 
 
 
@@ -60,4 +60,4 @@ using System.Reflection;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.8.20705.0")]
+[assembly: AssemblyVersion("1.8.20706.0")]
index 2823556..cc5e768 100644 (file)
@@ -93,5 +93,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyInformationalVersion("2012-07-05")]
-[assembly: AssemblyVersion("0.8.20705.0")]
+[assembly: AssemblyInformationalVersion("2012-07-06")]
+[assembly: AssemblyVersion("0.8.20706.0")]
index a42d7fa..e8923b0 100644 (file)
@@ -396,6 +396,7 @@ namespace Pithos.Core.Agents
 \r
                         var tuples = MergeSources(infos, files, states,moves).ToList();\r
 \r
+                        var processedPaths = new HashSet<string>();\r
                         //Process only the changes in the batch file, if one exists\r
                         var stateTuples = accountBatch==null?tuples:tuples.Where(t => accountBatch.Contains(t.FilePath));\r
                         foreach (var tuple in stateTuples.Where(s=>!s.Locked))\r
@@ -405,7 +406,7 @@ namespace Pithos.Core.Agents
                             //Set the Merkle Hash\r
                             //SetMerkleHash(accountInfo, tuple);\r
 \r
-                            await SyncSingleItem(accountInfo, tuple, agent, moves,token).ConfigureAwait(false);\r
+                            await SyncSingleItem(accountInfo, tuple, agent, moves,processedPaths,token).ConfigureAwait(false);\r
 \r
                         }\r
 \r
@@ -480,10 +481,14 @@ namespace Pithos.Core.Agents
             Pause = false;\r
         }\r
 \r
-        private async Task SyncSingleItem(AccountInfo accountInfo, StateTuple tuple, FileAgent agent, ConcurrentDictionary<string, MovedEventArgs> moves, CancellationToken token)\r
+        private async Task SyncSingleItem(AccountInfo accountInfo, StateTuple tuple, FileAgent agent, ConcurrentDictionary<string, MovedEventArgs> moves,HashSet<string> processedPaths, CancellationToken token)\r
         {\r
             Log.DebugFormat("Sync [{0}] C:[{1}] L:[{2}] S:[{3}]", tuple.FilePath, tuple.C, tuple.L, tuple.S);\r
 \r
+            //If the processed paths already contain the current path, exit\r
+            if (!processedPaths.Add(tuple.FilePath))\r
+                return;\r
+\r
             try\r
             {\r
                 bool isInferredParent = tuple.ObjectInfo != null && tuple.ObjectInfo.UUID.StartsWith("00000000-0000-0000");\r
@@ -584,7 +589,7 @@ namespace Pithos.Core.Agents
                                 //to avoid an expensive hash\r
                                 if (!MoveForLocalMove(accountInfo, tuple))\r
                                 {\r
-                                    await UploadLocalFile(accountInfo, tuple, token, isCreation, localInfo, progress).ConfigureAwait(false);\r
+                                    await UploadLocalFile(accountInfo, tuple, token, isCreation, localInfo,processedPaths, progress).ConfigureAwait(false);\r
                                 }\r
 \r
                                 //updateRecord( S = C )\r
@@ -592,7 +597,7 @@ namespace Pithos.Core.Agents
                                 \r
                                 if (isCreation )\r
                                 {                                    \r
-                                    ProcessChildren(accountInfo, tuple, agent, moves,token);\r
+                                    ProcessChildren(accountInfo, tuple, agent, moves,processedPaths,token);\r
                                 }\r
                             }\r
                         }\r
@@ -650,8 +655,6 @@ namespace Pithos.Core.Agents
             {\r
                 //In case of error log and retry with the next poll\r
                 Log.ErrorFormat("[SYNC] Failed for file {0}. Will Retry.\r\n{1}",tuple.FilePath,exc);\r
-\r
-                \r
             }\r
         }\r
 \r
@@ -684,7 +687,7 @@ namespace Pithos.Core.Agents
         }\r
 \r
         private async Task UploadLocalFile(AccountInfo accountInfo, StateTuple tuple, CancellationToken token,\r
-                                     bool isUnselectedRootFolder, FileSystemInfo localInfo, Progress<double> progress)\r
+                                     bool isUnselectedRootFolder, FileSystemInfo localInfo, HashSet<string> processedPaths, Progress<double> progress)\r
         {\r
             var action = new CloudUploadAction(accountInfo, localInfo, tuple.FileState,\r
                                                accountInfo.BlockSize, accountInfo.BlockHash,\r
@@ -697,13 +700,18 @@ namespace Pithos.Core.Agents
 \r
             if (isUnselectedRootFolder)\r
             {\r
-                var dirActions =\r
+                var dirActions =(\r
                     from dir in ((DirectoryInfo) localInfo).EnumerateDirectories("*", SearchOption.AllDirectories)\r
                     let subAction = new CloudUploadAction(accountInfo, dir, null,\r
                                                           accountInfo.BlockSize, accountInfo.BlockHash,\r
                                                           "Poll", true, token, progress)\r
-                    select NetworkAgent.Uploader.UploadCloudFile(subAction, token);\r
-                await TaskEx.WhenAll(dirActions.ToArray());\r
+                    select subAction).ToList();\r
+                foreach (var dirAction in dirActions)\r
+                {\r
+                    processedPaths.Add(dirAction.LocalFile.FullName);\r
+                }\r
+                \r
+                await TaskEx.WhenAll(dirActions.Select(a=>NetworkAgent.Uploader.UploadCloudFile(a,token)).ToArray());\r
             }\r
         }\r
 \r
@@ -806,7 +814,7 @@ namespace Pithos.Core.Agents
             }\r
         }\r
 \r
-        private void ProcessChildren(AccountInfo accountInfo, StateTuple tuple, FileAgent agent, ConcurrentDictionary<string, MovedEventArgs> moves,CancellationToken token)\r
+        private void ProcessChildren(AccountInfo accountInfo, StateTuple tuple, FileAgent agent, ConcurrentDictionary<string, MovedEventArgs> moves,HashSet<string> processedPaths,CancellationToken token)\r
         {\r
 \r
             var dirInfo = tuple.FileInfo as DirectoryInfo;\r
@@ -816,9 +824,9 @@ namespace Pithos.Core.Agents
                              select new StateTuple(file){C=file.ComputeShortHash(this.StatusNotification)};\r
             \r
             //Process folders first, to ensure folders appear on the sever as soon as possible\r
-            folderTuples.ApplyAction(t =>SyncSingleItem(accountInfo, t, agent, moves, token).Wait());\r
+            folderTuples.ApplyAction(t => SyncSingleItem(accountInfo, t, agent, moves, processedPaths,token).Wait());\r
             \r
-            fileTuples.ApplyAction(t => SyncSingleItem(accountInfo, t, agent, moves, token).Wait());\r
+            fileTuples.ApplyAction(t => SyncSingleItem(accountInfo, t, agent, moves,processedPaths, token).Wait());\r
         }\r
 \r
 \r
index 38ca677..facd42f 100644 (file)
@@ -15,17 +15,17 @@ namespace Pithos.Core.Agents
     public class Selectives\r
     {\r
 \r
-        public ConcurrentDictionary<Uri, List<Uri>> SelectiveUris { get; private set; }\r
+        public ConcurrentDictionary<Uri, ConcurrentBag<Uri>> SelectiveUris { get; private set; }\r
 \r
-        public ConcurrentDictionary<Uri, List<string>> SelectivePaths { get; private set; }\r
+        public ConcurrentDictionary<Uri, ConcurrentBag<string>> SelectivePaths { get; private set; }\r
 \r
         [Import]\r
         public IPithosSettings Settings { get; set; }\r
 \r
         public Selectives()\r
         {\r
-            SelectiveUris = new ConcurrentDictionary<Uri, List<Uri>>();\r
-            SelectivePaths = new ConcurrentDictionary<Uri, List<string>>();\r
+            SelectiveUris = new ConcurrentDictionary<Uri, ConcurrentBag<Uri>>();\r
+            SelectivePaths = new ConcurrentDictionary<Uri, ConcurrentBag<string>>();\r
         }\r
 \r
         readonly Dictionary<Uri, bool> _selectiveEnabled = new Dictionary<Uri, bool>();\r
@@ -61,8 +61,8 @@ namespace Pithos.Core.Agents
 \r
         public void SetSelectedUris(AccountInfo account,List<Uri> uris)\r
         {\r
-            SelectiveUris[account.AccountKey] = uris;\r
-            SelectivePaths[account.AccountKey] = UrisToFilePaths(account,uris);\r
+            SelectiveUris[account.AccountKey] = new ConcurrentBag<Uri>(uris);\r
+            SelectivePaths[account.AccountKey] = new ConcurrentBag<string>(UrisToFilePaths(account,uris));\r
         }\r
 \r
         public void AddUri(AccountInfo account,Uri uri)\r
@@ -91,7 +91,7 @@ namespace Pithos.Core.Agents
             if (!selectiveEnabled)\r
                 return !isShared;\r
 \r
-            List<Uri> filterUris;\r
+            ConcurrentBag<Uri> filterUris;\r
             return SelectiveUris.TryGetValue(account.AccountKey, out filterUris) \r
                 /*|| filterUris.Count ==0*/\r
                 && filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f));\r
@@ -112,7 +112,7 @@ namespace Pithos.Core.Agents
             if (!selectiveEnabled)\r
                 return !isShared;\r
 \r
-            List<string> paths;\r
+            ConcurrentBag<string> paths;\r
             var hasSelectives = SelectivePaths.TryGetValue(account.AccountKey, out paths);\r
             var isSelected = hasSelectives && paths.Any(fullPath.IsAtOrDirectlyBelow);\r
             return isSelected;\r
index 1bc522c..c65ef84 100644 (file)
@@ -40,6 +40,7 @@
  */\r
 #endregion\r
 using System;\r
+using System.Collections.Concurrent;\r
 using System.Collections.Generic;\r
 using System.ComponentModel.Composition;\r
 using System.Diagnostics.Contracts;\r
@@ -487,7 +488,7 @@ namespace Pithos.Core
             //var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey);\r
             if (!Selectives.IsSelectiveEnabled(_accountInfo.AccountKey)) return;\r
 \r
-            List<string> selectivePaths;\r
+            ConcurrentBag<string> selectivePaths;\r
             if (Selectives.SelectivePaths.TryGetValue(_accountInfo.AccountKey, out selectivePaths))\r
             {\r
                 var statePaths= FileState.Queryable.Select(state => state.FilePath).ToList();\r