Minor fix in Selective sync to ignore 403 errors the first time new share listings...
[pithos-ms-client] / trunk / Pithos.Core / Agents / PollAgent.cs
index 3483559..d1974bf 100644 (file)
@@ -79,13 +79,34 @@ namespace Pithos.Core.Agents
         [System.ComponentModel.Composition.Import]\r
         public NetworkAgent NetworkAgent { get; set; }\r
 \r
+        [System.ComponentModel.Composition.Import]\r
+        public Selectives Selectives { get; set; }\r
+\r
         public IStatusNotification StatusNotification { get; set; }\r
 \r
+        public bool Pause\r
+        {\r
+            get {\r
+                return _pause;\r
+            }\r
+            set {\r
+                _pause = value;                \r
+                if (!_pause)\r
+                    _unPauseEvent.Set();\r
+                else\r
+                {\r
+                    _unPauseEvent.Reset();\r
+                }\r
+            }\r
+        }\r
+\r
         private bool _firstPoll = true;\r
 \r
         //The Sync Event signals a manual synchronisation\r
         private readonly AsyncManualResetEvent _syncEvent = new AsyncManualResetEvent();\r
 \r
+        private readonly AsyncManualResetEvent _unPauseEvent = new AsyncManualResetEvent(true);\r
+\r
         private readonly ConcurrentDictionary<string, DateTime> _lastSeen = new ConcurrentDictionary<string, DateTime>();\r
         private readonly ConcurrentDictionary<Uri, AccountInfo> _accounts = new ConcurrentDictionary<Uri,AccountInfo>();\r
 \r
@@ -117,6 +138,7 @@ namespace Pithos.Core.Agents
                 var nextSince = since;\r
                 try\r
                 {\r
+                    await _unPauseEvent.WaitAsync();\r
                     UpdateStatus(PithosStatus.PollSyncing);\r
 \r
                     var tasks = from accountInfo in _accounts.Values\r
@@ -164,8 +186,12 @@ namespace Pithos.Core.Agents
         {\r
             var sync = _syncEvent.WaitAsync();\r
             var wait = TaskEx.Delay(TimeSpan.FromSeconds(Settings.PollingInterval), NetworkAgent.CancellationToken);\r
+            \r
             var signaledTask = await TaskEx.WhenAny(sync, wait);\r
-\r
+            \r
+            //Pausing takes precedence over manual sync or awaiting\r
+            _unPauseEvent.Wait();\r
+            \r
             //Wait for network processing to finish before polling\r
             var pauseTask=NetworkAgent.ProceedEvent.WaitAsync();\r
             await TaskEx.WhenAll(signaledTask, pauseTask);\r
@@ -274,7 +300,7 @@ namespace Pithos.Core.Agents
                         \r
                         var differencer = _differencer.PostSnapshot(accountInfo, cleanRemotes);\r
 \r
-                        var filterUris = SelectiveUris[accountInfo.AccountKey];\r
+                        var filterUris = Selectives.SelectiveUris[accountInfo.AccountKey];\r
 \r
                         ProcessDeletedFiles(accountInfo, differencer.Deleted.FilterDirectlyBelow(filterUris));\r
 \r
@@ -295,6 +321,7 @@ namespace Pithos.Core.Agents
                             .Except(NetworkAgent.GetEnumerable(), new LocalFileComparer())\r
                             .ToList();\r
 \r
+                        await _unPauseEvent.WaitAsync();\r
                         //Queue all the actions\r
                         foreach (var message in distinctActions)\r
                         {\r
@@ -355,6 +382,7 @@ namespace Pithos.Core.Agents
 \r
         readonly AccountsDifferencer _differencer = new AccountsDifferencer();\r
         private Dictionary<Uri, List<Uri>> _selectiveUris = new Dictionary<Uri, List<Uri>>();\r
+        private bool _pause;\r
 \r
         /// <summary>\r
         /// Deletes local files that are not found in the list of cloud files\r
@@ -607,17 +635,6 @@ namespace Pithos.Core.Agents
             }\r
         }\r
 \r
-        public void SetSyncUris(Uri accountKey, Uri[] uris)\r
-        {            \r
-            SelectiveUris[accountKey]=uris.ToList();\r
-        }\r
-\r
-        protected Dictionary<Uri,List<Uri>> SelectiveUris\r
-        {\r
-            get { return _selectiveUris;}\r
-            set { _selectiveUris = value; }\r
-        }\r
-\r
         public void AddAccount(AccountInfo accountInfo)\r
         {\r
             //Avoid adding a duplicate accountInfo\r
@@ -643,36 +660,44 @@ namespace Pithos.Core.Agents
             var client = new CloudFilesClient(accountInfo);\r
             foreach (var folderUri in added)\r
             {\r
-                string account;\r
-                string container;\r
-                var segmentsCount = folderUri.Segments.Length;\r
-                if (segmentsCount < 3)\r
-                    continue;\r
-                if (segmentsCount==3)\r
-                {\r
-                    account = folderUri.Segments[1].TrimEnd('/');\r
-                    container = folderUri.Segments[2].TrimEnd('/');                    \r
-                }\r
-                else\r
-                {\r
-                    account = folderUri.Segments[2].TrimEnd('/');\r
-                    container = folderUri.Segments[3].TrimEnd('/');                    \r
-                }\r
-                IList<ObjectInfo> items;\r
-                if(segmentsCount>3)\r
+                try\r
                 {\r
-                    var folder =String.Join("", folderUri.Segments.Splice(4));\r
-                    items = client.ListObjects(account, container, folder);\r
+\r
+                    string account;\r
+                    string container;\r
+                    var segmentsCount = folderUri.Segments.Length;\r
+                    if (segmentsCount < 3)\r
+                        continue;\r
+                    if (segmentsCount == 3)\r
+                    {\r
+                        account = folderUri.Segments[1].TrimEnd('/');\r
+                        container = folderUri.Segments[2].TrimEnd('/');\r
+                    }\r
+                    else\r
+                    {\r
+                        account = folderUri.Segments[2].TrimEnd('/');\r
+                        container = folderUri.Segments[3].TrimEnd('/');\r
+                    }\r
+                    IList<ObjectInfo> items;\r
+                    if (segmentsCount > 3)\r
+                    {\r
+                        var folder = String.Join("", folderUri.Segments.Splice(4));\r
+                        items = client.ListObjects(account, container, folder);\r
+                    }\r
+                    else\r
+                    {\r
+                        items = client.ListObjects(account, container);\r
+                    }\r
+                    var actions = CreatesToActions(accountInfo, items);\r
+                    foreach (var action in actions)\r
+                    {\r
+                        NetworkAgent.Post(action);\r
+                    }\r
                 }\r
-                else\r
+                catch (Exception exc)\r
                 {\r
-                    items = client.ListObjects(account, container);\r
+                    Log.WarnFormat("Listing of new selective path [{0}] failed with \r\n{1}", folderUri, exc);\r
                 }\r
-                var actions=CreatesToActions(accountInfo, items);\r
-                foreach (var action in actions)\r
-                {\r
-                    NetworkAgent.Post(action);    \r
-                }                \r
             }\r
 \r
             //Need to get a listing of each of the URLs, then post them to the NetworkAgent\r