Some timeout issues
authorpkanavos <pkanavos@gmail.com>
Fri, 28 Sep 2012 15:32:38 +0000 (18:32 +0300)
committerpkanavos <pkanavos@gmail.com>
Fri, 28 Sep 2012 15:32:38 +0000 (18:32 +0300)
16 files changed:
trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs
trunk/Pithos.Client.WPF/FileProperties/ConflictResolver.cs
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Core/Agents/DeleteAgent.cs
trunk/Pithos.Core/Agents/Downloader.cs
trunk/Pithos.Core/Agents/IdleBatch.cs
trunk/Pithos.Core/Agents/Notifier.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Core/Agents/Uploader.cs
trunk/Pithos.Core/IStatusNotification.cs
trunk/Pithos.Core/Pithos.Core.csproj
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.Network/ICloudClient.cs
trunk/Pithos.Network/Pithos.Network.csproj
trunk/Pithos.Network/WebExtensions.cs

index fa24bab..2036ac8 100644 (file)
-#region
-/* -----------------------------------------------------------------------
- * <copyright file="PithosSettings.cs" company="GRNet">
- * 
- * Copyright 2011-2012 GRNET S.A. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- *   1. Redistributions of source code must retain the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials
- *      provided with the distribution.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either expressed
- * or implied, of GRNET S.A.
- * </copyright>
- * -----------------------------------------------------------------------
- */
-#endregion
-using System.ComponentModel.Composition;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using Pithos.Client.WPF.Properties;
-using Pithos.Interfaces;
-using log4net.Appender;
-using log4net.Core;
-using log4net.Repository.Hierarchy;
-
-namespace Pithos.Client.WPF.Configuration
-{
-    using System;
-
-    [Export(typeof(IPithosSettings))]
-    [Export]
-    public class PithosSettings :  IPithosSettings
-    {
-        private readonly Settings _settings = Settings.Default;
-
-        public PithosSettings()
-        {
-            //Settings should already be upgraded by the time we reach this point
-            Debug.Assert(!_settings.MustUpgrade);
-            //_settings.Upgrade();
-        }
-
-        public bool UseDefaultProxy
-        {
-            get { return _settings.UseDefaultProxy; }
-            set { _settings.UseDefaultProxy = value; }
-        }
-
-        public bool UseManualProxy
-        {
-            get { return _settings.UseManualProxy; }
-            set { _settings.UseManualProxy = value; }
-        }
-
-        public bool UseNoProxy
-        {
-            get { return _settings.UseNoProxy; }
-            set { _settings.UseNoProxy = value; }
-        }
-
-        public string PithosPath
-        {
-            get { return _settings.PithosPath; }
-            set { _settings.PithosPath = value; }
-        }
-
-      /*  public string PithosSite
-        {
-            get { return _settings.PithosSite; }
-        }*/
-
-
-        public string IconsPath
-        {
-            get { return _settings.IconPath; }
-            set { _settings.IconPath = value; }
-        }
-
-        public string UserName
-        {
-            get { return _settings.UserName; }
-            set { _settings.UserName = value; }
-        }
-
-        public string ApiKey
-        {
-            get { return _settings.ApiKey; }
-            set { _settings.ApiKey = value; }
-        }
-
-        public AccountsCollection Accounts
-        {
-            get { return _settings.Accounts ?? (_settings.Accounts = new AccountsCollection()); }
-            set { _settings.Accounts = value; }
-        }
-
-        public string ProxyServer
-        {
-            get { return _settings.ProxyServer; }
-            set { _settings.ProxyServer = value; }
-        }
-
-        public int ProxyPort
-        {
-            get { return _settings.ProxyPort; }
-            set { _settings.ProxyPort = value; }
-        }
-
-        public string ProxyUsername
-        {
-            get { return _settings.ProxyUsername; }
-            set { _settings.ProxyUsername = value; }
-        }
-
-
-        public string ProxyPassword
-        {
-            get { return _settings.ProxyPassword; }
-            set { _settings.ProxyPassword = value; }
-        }
-
-        public string ProxyDomain
-        {
-            get { return _settings.ProxyDomain; }
-            set { _settings.ProxyDomain = value; }
-        }
-
-        public bool ProxyAuthentication
-        {
-
-            get { return _settings.ProxyAuthentication; }
-            set { _settings.ProxyAuthentication = value; }
-        }
-
-        
-        
-        public bool ExtensionsActivated
-        {
-
-            get { return _settings.ExtensionsActivated; }
-            set { _settings.ExtensionsActivated = value; }
-        }
-
-        public bool ShowDesktopNotifications
-        {
-            get { return _settings.ShowDesktopNotifications; }
-            set { _settings.ShowDesktopNotifications = value; }
-        }
-
-
-        public int PollingInterval
-        {
-            get { return _settings.PollingInterval; }
-            set
-            {
-                if (value <= 0)
-                    throw new ArgumentOutOfRangeException();
-                _settings.PollingInterval = value;
-            }
-        }
-
-        public TimeSpan StartupDelay
-        {
-            get { return _settings.StartupDelay; }
-            set
-            {
-                if (value < TimeSpan.Zero)
-                    throw new ArgumentOutOfRangeException();
-                _settings.StartupDelay = value;
-            }
-        }
-
-
-        public bool StartOnSystemStartup
-        {
-            get { return _settings.StartOnSystemStartup; }
-            set
-            {
-                _settings.StartOnSystemStartup = value;
-            }
-        }
-
-        public byte HashingParallelism
-        {
-            get { return _settings.HashingParallelism; }
-            set { _settings.HashingParallelism = value; }
-        }
-
-        public string UpdateUrl
-        {
-            get { return _settings.UpdateUrl; }
-        }
-
-        public bool UpdateDiagnostics
-        {
-            get { return _settings.UpdateDiagnostics; }
-        }
-
-        public TimeSpan UpdateCheckInterval
-        {
-            get { return _settings.UpdateCheckInterval; }
-        }
-
-        public TimeSpan FileIdleTimeout
-        {
-            get { return _settings.FileIdleTimeout; }
-        }
-
-        public bool UpdateForceCheck
-        {
-            get { return _settings.UpdateForceCheck; }
-        }
-
-        public bool DebugLoggingEnabled
-        {
-            get { return _settings.DebugLoggingEnabled; }
-            set
-            {
-                _settings.DebugLoggingEnabled = value;
-
-                SetDebugLevel();
-            }
-        }
-
-        public bool IgnoreCertificateErrors
-        {
-            get { return _settings.IgnoreCertificateErrors; }
-            set
-            {
-                _settings.IgnoreCertificateErrors = value;
-
-            }
-        }
-
-        private static void SetDebugLevel()
-        {
-            var loggerRepository = (Hierarchy) log4net.LogManager.GetRepository();
-
-            var appenders = loggerRepository.GetAppenders();
-
-            var debugAppender = appenders.OfType<RollingFileAppender>()
-                .FirstOrDefault(a => a.Name == "DebugFileAppender");
-            if (debugAppender != null)
-            {
-                var pithosDataPath = PithosDataPath;
-                debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
-                debugAppender.Threshold = !Settings.Default.DebugLoggingEnabled ? Level.Off : Level.All;
-                debugAppender.ActivateOptions();
-            }
-        }
-
-        public static string PithosDataPath
-        {
-            get
-            {
-                var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
-                var pithosDataPath = Path.Combine(appDataPath, "GRNET\\PITHOS");
-                return pithosDataPath;
-            }
-        }
-
-        public void Save()
-        {
-            _settings.Save();
-            Proxy.SetFromSettings(this);
-        }
-
-        public void Reload()
-        {
-            _settings.Reload();
-        }
-
-        public void Reset()
-        {
-            _settings.Reset();
-            _settings.Save();
-        }
-    }
-}
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="PithosSettings.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System.ComponentModel.Composition;\r
+using System.Diagnostics;\r
+using System.IO;\r
+using System.Linq;\r
+using Pithos.Client.WPF.Properties;\r
+using Pithos.Interfaces;\r
+using log4net.Appender;\r
+using log4net.Core;\r
+using log4net.Repository.Hierarchy;\r
+\r
+namespace Pithos.Client.WPF.Configuration\r
+{\r
+    using System;\r
+\r
+    [Export(typeof(IPithosSettings))]\r
+    [Export]\r
+    public class PithosSettings :  IPithosSettings\r
+    {\r
+        private readonly Settings _settings = Settings.Default;\r
+\r
+        public PithosSettings()\r
+        {\r
+            //Settings should already be upgraded by the time we reach this point\r
+            Debug.Assert(!_settings.MustUpgrade);\r
+            //_settings.Upgrade();\r
+        }\r
+\r
+        public bool UseDefaultProxy\r
+        {\r
+            get { return _settings.UseDefaultProxy; }\r
+            set { _settings.UseDefaultProxy = value; }\r
+        }\r
+\r
+        public bool UseManualProxy\r
+        {\r
+            get { return _settings.UseManualProxy; }\r
+            set { _settings.UseManualProxy = value; }\r
+        }\r
+\r
+        public bool UseNoProxy\r
+        {\r
+            get { return _settings.UseNoProxy; }\r
+            set { _settings.UseNoProxy = value; }\r
+        }\r
+\r
+        public string PithosPath\r
+        {\r
+            get { return _settings.PithosPath; }\r
+            set { _settings.PithosPath = value; }\r
+        }\r
+\r
+      /*  public string PithosSite\r
+        {\r
+            get { return _settings.PithosSite; }\r
+        }*/\r
+\r
+\r
+        public string IconsPath\r
+        {\r
+            get { return _settings.IconPath; }\r
+            set { _settings.IconPath = value; }\r
+        }\r
+\r
+        public string UserName\r
+        {\r
+            get { return _settings.UserName; }\r
+            set { _settings.UserName = value; }\r
+        }\r
+\r
+        public string ApiKey\r
+        {\r
+            get { return _settings.ApiKey; }\r
+            set { _settings.ApiKey = value; }\r
+        }\r
+\r
+        public AccountsCollection Accounts\r
+        {\r
+            get { return _settings.Accounts ?? (_settings.Accounts = new AccountsCollection()); }\r
+            set { _settings.Accounts = value; }\r
+        }\r
+\r
+        public string ProxyServer\r
+        {\r
+            get { return _settings.ProxyServer; }\r
+            set { _settings.ProxyServer = value; }\r
+        }\r
+\r
+        public int ProxyPort\r
+        {\r
+            get { return _settings.ProxyPort; }\r
+            set { _settings.ProxyPort = value; }\r
+        }\r
+\r
+        public string ProxyUsername\r
+        {\r
+            get { return _settings.ProxyUsername; }\r
+            set { _settings.ProxyUsername = value; }\r
+        }\r
+\r
+\r
+        public string ProxyPassword\r
+        {\r
+            get { return _settings.ProxyPassword; }\r
+            set { _settings.ProxyPassword = value; }\r
+        }\r
+\r
+        public string ProxyDomain\r
+        {\r
+            get { return _settings.ProxyDomain; }\r
+            set { _settings.ProxyDomain = value; }\r
+        }\r
+\r
+        public bool ProxyAuthentication\r
+        {\r
+\r
+            get { return _settings.ProxyAuthentication; }\r
+            set { _settings.ProxyAuthentication = value; }\r
+        }\r
+\r
+        \r
+        \r
+        public bool ExtensionsActivated\r
+        {\r
+\r
+            get { return _settings.ExtensionsActivated; }\r
+            set { _settings.ExtensionsActivated = value; }\r
+        }\r
+\r
+        public bool ShowDesktopNotifications\r
+        {\r
+            get { return _settings.ShowDesktopNotifications; }\r
+            set { _settings.ShowDesktopNotifications = value; }\r
+        }\r
+\r
+\r
+        public int PollingInterval\r
+        {\r
+            get { return _settings.PollingInterval; }\r
+            set\r
+            {\r
+                if (value <= 0)\r
+                    throw new ArgumentOutOfRangeException();\r
+                _settings.PollingInterval = value;\r
+            }\r
+        }\r
+\r
+        public TimeSpan StartupDelay\r
+        {\r
+            get { return _settings.StartupDelay; }\r
+            set\r
+            {\r
+                if (value < TimeSpan.Zero)\r
+                    throw new ArgumentOutOfRangeException();\r
+                _settings.StartupDelay = value;\r
+            }\r
+        }\r
+\r
+\r
+        public bool StartOnSystemStartup\r
+        {\r
+            get { return _settings.StartOnSystemStartup; }\r
+            set\r
+            {\r
+                _settings.StartOnSystemStartup = value;\r
+            }\r
+        }\r
+\r
+        public byte HashingParallelism\r
+        {\r
+            get { return _settings.HashingParallelism; }\r
+            set { _settings.HashingParallelism = value; }\r
+        }\r
+\r
+        public string UpdateUrl\r
+        {\r
+            get { return _settings.UpdateUrl; }\r
+        }\r
+\r
+        public bool UpdateDiagnostics\r
+        {\r
+            get { return _settings.UpdateDiagnostics; }\r
+        }\r
+\r
+        public TimeSpan UpdateCheckInterval\r
+        {\r
+            get { return _settings.UpdateCheckInterval; }\r
+        }\r
+\r
+        public TimeSpan FileIdleTimeout\r
+        {\r
+            get { return _settings.FileIdleTimeout; }\r
+        }\r
+\r
+        public bool UpdateForceCheck\r
+        {\r
+            get { return _settings.UpdateForceCheck; }\r
+        }\r
+\r
+        public bool DebugLoggingEnabled\r
+        {\r
+            get { return _settings.DebugLoggingEnabled; }\r
+            set\r
+            {\r
+                _settings.DebugLoggingEnabled = value;\r
+\r
+                SetDebugLevel();\r
+            }\r
+        }\r
+\r
+        public bool IgnoreCertificateErrors\r
+        {\r
+            get { return _settings.IgnoreCertificateErrors; }\r
+            set\r
+            {\r
+                _settings.IgnoreCertificateErrors = value;\r
+\r
+            }\r
+        }\r
+\r
+        private static void SetDebugLevel()\r
+        {\r
+            var loggerRepository = (Hierarchy) log4net.LogManager.GetRepository();\r
+\r
+            var appenders = loggerRepository.GetAppenders();\r
+\r
+            var debugAppender = appenders.OfType<RollingFileAppender>()\r
+                .FirstOrDefault(a => a.Name == "DebugFileAppender");\r
+            if (debugAppender != null)\r
+            {\r
+                var pithosDataPath = PithosDataPath;\r
+                debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");\r
+                debugAppender.Threshold = !Settings.Default.DebugLoggingEnabled ? Level.Off : Level.All;\r
+                debugAppender.ActivateOptions();\r
+            }\r
+        }\r
+\r
+        public static string PithosDataPath\r
+        {\r
+            get\r
+            {\r
+                var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);\r
+                var pithosDataPath = Path.Combine(appDataPath, "GRNET\\PITHOS");\r
+                return pithosDataPath;\r
+            }\r
+        }\r
+\r
+        public void Save()\r
+        {\r
+            LockedSave();\r
+            Proxy.SetFromSettings(this);\r
+        }\r
+\r
+        private void LockedSave()\r
+        {\r
+            lock (this)\r
+            {\r
+                _settings.Save();\r
+            }\r
+        }\r
+\r
+        public void Reload()\r
+        {\r
+            _settings.Reload();\r
+        }\r
+\r
+        public void Reset()\r
+        {\r
+            _settings.Reset();\r
+            LockedSave();\r
+        }\r
+    }\r
+}\r
index 8725bb6..ed3e002 100644 (file)
@@ -133,7 +133,7 @@ namespace Pithos.Client.WPF.FileProperties
 \r
         private void DeleteCloudFile(CloudUploadAction action)\r
         {\r
-            using (StatusNotification.GetNotifier("Deleting server {0}", "Deleted server {0}", Path.GetFileName(action.LocalFile.Name)))\r
+            using (StatusNotification.GetNotifier("Deleting server {0}", "Deleted server {0}", true,Path.GetFileName(action.LocalFile.Name)))\r
             {\r
 \r
                 StatusKeeper.SetFileState(action.LocalFile.FullName, FileStatus.Deleted,\r
index e63b513..404628d 100644 (file)
@@ -810,11 +810,12 @@ namespace Pithos.Client.WPF {
                return new Notifier(this, startNotification, endNotification);\r
            }*/\r
 \r
-           public Notifier GetNotifier(string startMessage, string endMessage, params object[] args)\r
+           public Notifier GetNotifier(string startMessage, string endMessage, bool isActive=true,params object[] args)\r
            {\r
-               return new Notifier(this, \r
+               return isActive?new Notifier(this, \r
                 new StatusNotification(String.Format(startMessage,args)), \r
-                new StatusNotification(String.Format(endMessage,args)));\r
+                new StatusNotification(String.Format(endMessage,args)))\r
+                :new Notifier(this,(Notification) null,null);\r
            }\r
 \r
 \r
index bb483e5..d9f883a 100644 (file)
@@ -201,7 +201,7 @@ namespace Pithos.Core.Agents
             _deleteAgent.Post(action);\r
         }\r
 \r
-        public void DeleteCloudFile(AccountInfo accountInfo, ObjectInfo cloudFile)\r
+        public async void DeleteCloudFile(AccountInfo accountInfo, ObjectInfo cloudFile)\r
         {\r
             if (accountInfo == null)\r
                 throw new ArgumentNullException("accountInfo");\r
@@ -229,7 +229,7 @@ namespace Pithos.Core.Agents
 \r
                 var client = new CloudFilesClient(accountInfo);\r
                 \r
-                client.DeleteObject(account, container, cloudFile.Name,cloudFile.IsDirectory);\r
+                await client.DeleteObject(account, container, cloudFile.Name,cloudFile.IsDirectory);\r
 \r
                 StatusKeeper.ClearFileStatus(fullPath);\r
                 StatusNotification.Notify(new CloudNotification{Data=cloudFile});\r
index 0fb9bd0..4843d7a 100644 (file)
@@ -68,7 +68,7 @@ namespace Pithos.Core.Agents
 \r
                     TreeHash localTreeHash;\r
 \r
-                    using (StatusNotification.GetNotifier("Hashing for Download {0}", "Hashed for Download {0}", fileName))\r
+                    using (StatusNotification.GetNotifier("Hashing for Download {0}", "Hashed for Download {0}", (info.Exists && info is FileInfo),fileName))\r
                     {\r
                         var state = StatusKeeper.GetStateByFilePath(filePath);\r
                         var progress = new Progress<HashProgress>(d =>\r
index 744c015..870e3ed 100644 (file)
-#region
-/* -----------------------------------------------------------------------
- * <copyright file="IdleBatch.cs" company="GRNet">
- * 
- * Copyright 2011-2012 GRNET S.A. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- *   1. Redistributions of source code must retain the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials
- *      provided with the distribution.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either expressed
- * or implied, of GRNET S.A.
- * </copyright>
- * -----------------------------------------------------------------------
- */
-#endregion
-
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks.Dataflow;
-using System;
-using log4net;
-
-namespace Pithos.Core.Agents
-{
-
-    /// <summary>
-    /// Calls a callback function if an idle timeout expires after the last post
-    /// </summary>
-    public class IdleBatch<T>
-    {
-        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
-        readonly Timer _triggerTimer;
-
-        private readonly BatchBlock<T> _batchBlock;
-        private readonly TransformBlock<T, T> _timerBlock;
-        private readonly ActionBlock<T[]> _processBlock;
-
-        private readonly int _timeOut;
-
-        public IdleBatch(int idleTimeout, Action<T[]> action)
-        {
-            _timeOut = idleTimeout;
-            _timerBlock = new TransformBlock<T, T>(t =>
-            {
-                _triggerTimer.Change(_timeOut, Timeout.Infinite);
-                return t;
-            });
-            _batchBlock = new BatchBlock<T>(9999);
-            _processBlock = new ActionBlock<T[]>(action);
-
-            _timerBlock.LinkTo(_batchBlock);
-            _batchBlock.LinkTo(_processBlock);
-
-            _timerBlock.Completion.ContinueWith(_ => _batchBlock.Complete());
-            _batchBlock.Completion.ContinueWith(_ => _processBlock.Complete());
-
-            _triggerTimer = new Timer(_ => _batchBlock.TriggerBatch());
-        }
-
-        public void Post(T input)
-        {
-            _timerBlock.Post(input);
-        }
-
-        public int Count
-        {
-            get { return _timerBlock.InputCount; }
-        }
-
-        public void ForceTrigger()
-        {
-            _batchBlock.TriggerBatch();
-            _timerBlock.Complete();
-            _processBlock.Completion.Wait();
-        }
-    }
-
-}
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="IdleBatch.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+\r
+using System.Reflection;\r
+using System.Threading;\r
+using System.Threading.Tasks.Dataflow;\r
+using System;\r
+using log4net;\r
+\r
+namespace Pithos.Core.Agents\r
+{\r
+\r
+    /// <summary>\r
+    /// Calls a callback function if an idle timeout expires after the last post\r
+    /// </summary>\r
+    public class IdleBatch<T>\r
+    {\r
+        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);\r
+\r
+        readonly Timer _triggerTimer;\r
+\r
+        private readonly BatchBlock<T> _batchBlock;\r
+        //private readonly TransformBlock<T, T> _timerBlock;\r
+        private readonly ActionBlock<T[]> _processBlock;\r
+\r
+        private readonly int _timeOut;\r
+\r
+        private int _eventCount = 0;\r
+\r
+        private int _elapsedSeconds = 0;\r
+\r
+        private int _timeoutSeconds;\r
+\r
+        public IdleBatch(int idleTimeout, Action<T[]> action)\r
+        {\r
+            _timeOut = idleTimeout;\r
+          /*  _timerBlock = new TransformBlock<T, T>(t =>\r
+            {                \r
+                //_triggerTimer.Change(_timeOut, Timeout.Infinite);\r
+                return t;\r
+            });*/\r
+            _batchBlock = new BatchBlock<T>(99999);\r
+            _processBlock = new ActionBlock<T[]>(action);\r
+\r
+            //_timerBlock.LinkTo(_batchBlock);\r
+            _batchBlock.LinkTo(_processBlock);\r
+\r
+            //_timerBlock.Completion.ContinueWith(_ => _batchBlock.Complete());\r
+            _batchBlock.Completion.ContinueWith(_ => _processBlock.Complete());\r
+\r
+            _timeoutSeconds = idleTimeout/2000;\r
+\r
+            _triggerTimer = new Timer(_ =>OnTimer(), null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));           \r
+        }\r
+\r
+        private void OnTimer()\r
+        {\r
+            \r
+            //If there were any events, restart counting\r
+            if ( 0!= Interlocked.Exchange(ref _eventCount, 0))\r
+            {\r
+                _elapsedSeconds = 0;\r
+                return;\r
+            }\r
+\r
+            \r
+            //Once we reach the target idle seconds, trigger\r
+            if (Interlocked.CompareExchange(ref _elapsedSeconds,0,10)>=10)\r
+            {                \r
+                _batchBlock.TriggerBatch();\r
+            }\r
+            else\r
+            {\r
+                Interlocked.Increment(ref _elapsedSeconds);\r
+            }\r
+        }\r
+\r
+        public void Post(T input)\r
+        {\r
+            Interlocked.Add(ref _eventCount, 1); \r
+            _batchBlock.SendAsync(input);\r
+        }\r
+\r
+        public int Count\r
+        {\r
+            get { return _batchBlock.OutputCount; }\r
+        }\r
+\r
+        public void ForceTrigger()\r
+        {\r
+            _batchBlock.TriggerBatch();\r
+            _batchBlock.Complete();\r
+            _processBlock.Completion.Wait();\r
+        }\r
+    }\r
+\r
+}\r
index 6e3fa43..8468fdf 100644 (file)
@@ -1,48 +1,51 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Pithos.Core
-{
-    public class Notifier:IDisposable
-    {
-        private readonly IStatusNotification _statusNotification;
-
-        private readonly Notification _endNotification;
-
-        public Notifier(IStatusNotification statusNotification,string startMessage,string endMessage)
-            :this(statusNotification,new Notification{Message=startMessage},new Notification{Message=endMessage} )
-        {
-            
-        }
-
-        public Notifier(IStatusNotification statusNotification,Notification startNotification,Notification endNotification)
-        {
-            _statusNotification = statusNotification;
-            _endNotification = endNotification;
-            _statusNotification.Notify(startNotification);
-        }
-
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        ~Notifier()
-        {
-            Dispose(false);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                _statusNotification.Notify(_endNotification);        
-            }
-        }
-    }
-}
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Threading.Tasks;\r
+\r
+namespace Pithos.Core\r
+{\r
+    public class Notifier:IDisposable\r
+    {\r
+        private readonly IStatusNotification _statusNotification;\r
+\r
+        private readonly Notification _endNotification;\r
+\r
+        public Notifier(IStatusNotification statusNotification,string startMessage,string endMessage)\r
+            :this(statusNotification,new Notification{Message=startMessage},new Notification{Message=endMessage} )\r
+        {\r
+            \r
+        }\r
+\r
+        public Notifier(IStatusNotification statusNotification,Notification startNotification,Notification endNotification)\r
+        {\r
+            _statusNotification = statusNotification;\r
+            _endNotification = endNotification;\r
+            \r
+            if (startNotification!=null)\r
+                _statusNotification.Notify(startNotification);\r
+        }\r
+\r
+\r
+        public void Dispose()\r
+        {\r
+            Dispose(true);\r
+            GC.SuppressFinalize(this);\r
+        }\r
+\r
+        ~Notifier()\r
+        {\r
+            Dispose(false);\r
+        }\r
+\r
+        protected virtual void Dispose(bool disposing)\r
+        {\r
+            if (disposing)\r
+            {\r
+                if (_endNotification!=null)\r
+                    _statusNotification.Notify(_endNotification);        \r
+            }\r
+        }\r
+    }\r
+}\r
index c95d6af..f496a38 100644 (file)
@@ -531,7 +531,7 @@ namespace Pithos.Core.Agents
                             //Server file doesn't exist\r
                             //deleteObjectFromLocal()\r
                             using (\r
-                                StatusNotification.GetNotifier("Deleting local {0}", "Deleted local {0}",\r
+                                StatusNotification.GetNotifier("Deleting local {0}", "Deleted local {0}",true,\r
                                                                localInfo.Name))\r
                             {\r
                                 DeleteLocalFile(agent, localFilePath);\r
@@ -543,7 +543,7 @@ namespace Pithos.Core.Agents
                             //downloadServerObject() // Result: L = S\r
                             //If the file has moved on the server, move it locally before downloading\r
                             using (\r
-                                StatusNotification.GetNotifier("Downloading {0}", "Downloaded {0}",\r
+                                StatusNotification.GetNotifier("Downloading {0}", "Downloaded {0}",true,\r
                                                                localInfo.Name))\r
                             {\r
                                 var targetPath = MoveForServerMove(accountInfo, tuple);\r
@@ -698,7 +698,7 @@ namespace Pithos.Core.Agents
                                                accountInfo.BlockSize, accountInfo.BlockHash,\r
                                                "Poll", isUnselectedRootFolder, token, progress,tuple.Merkle);            \r
             \r
-            using (StatusNotification.GetNotifier("Uploading {0}", "Uploaded {0}",\r
+            using (StatusNotification.GetNotifier("Uploading {0}", "Uploaded {0}",true,\r
                                                   localInfo.Name))\r
             {\r
                 await NetworkAgent.Uploader.UploadCloudFile(action, token).ConfigureAwait(false);\r
@@ -751,7 +751,7 @@ namespace Pithos.Core.Agents
                 //TODO: SImplify these multiple conversions from and to Uris\r
                 var oldName = tuple.OldFullPath.AsRelativeTo(containerPath);\r
                 //Then execute a move instead of an upload\r
-                using (StatusNotification.GetNotifier("Moving {0}", "Moved {0}", tuple.FileInfo.Name))\r
+                using (StatusNotification.GetNotifier("Moving {0}", "Moved {0}", true,tuple.FileInfo.Name))\r
                 {\r
                     client.MoveObject(objectInfo.Account, objectInfo.Container, oldName.ToEscapedUri(),\r
                                                           objectInfo.Container, objectInfo.Name);\r
@@ -823,7 +823,7 @@ namespace Pithos.Core.Agents
                 return serverPath;\r
             }\r
 \r
-            using (StatusNotification.GetNotifier("Moving local {0}", "Moved local {0}", Path.GetFileName(tuple.FilePath)))\r
+            using (StatusNotification.GetNotifier("Moving local {0}", "Moved local {0}", true,Path.GetFileName(tuple.FilePath)))\r
             using(NetworkGate.Acquire(tuple.FilePath,NetworkOperation.Renaming))\r
             {\r
                     \r
@@ -852,7 +852,7 @@ namespace Pithos.Core.Agents
 \r
         private void DeleteCloudFile(AccountInfo accountInfo, StateTuple tuple)\r
         {\r
-            using (StatusNotification.GetNotifier("Deleting server {0}", "Deleted server {0}", Path.GetFileName(tuple.FilePath)))\r
+            using (StatusNotification.GetNotifier("Deleting server {0}", "Deleted server {0}", true,Path.GetFileName(tuple.FilePath)))\r
             {\r
 \r
                 StatusKeeper.SetFileState(tuple.FilePath, FileStatus.Deleted,\r
index 91a183f..18befc9 100644 (file)
@@ -282,7 +282,7 @@ namespace Pithos.Core.Agents
         private void ProcessFile(ISession session,int total, System.Tuple<FileInfo, FileState> pair)\r
         {\r
             var idx = Interlocked.Increment(ref i);\r
-            using (StatusNotification.GetNotifier("Indexing file {0} of {1}", "Indexed file {0} of {1} ", idx, total))\r
+            using (StatusNotification.GetNotifier("Indexing file {0} of {1}", "Indexed file {0} of {1} ", true,idx, total))\r
             {\r
                 var fileState = pair.Item2;\r
                 var file = pair.Item1;\r
index 18da934..2941cef 100644 (file)
@@ -59,7 +59,8 @@ namespace Pithos.Core.Agents
                         action.FileState = StatusKeeper.GetStateByFilePath(fileInfo.FullName);\r
 \r
                     TreeHash localTreeHash;\r
-                    using (StatusNotification.GetNotifier("Merkle Hashing for Upload {0}", "Merkle Hashed for Upload {0}", fileInfo.Name))\r
+                    var isLarge = ((fileInfo as FileInfo).NullSafe(f => f.Length) >= action.AccountInfo.BlockSize);\r
+                    using (StatusNotification.GetNotifier("Merkle Hashing for Upload {0}", "Merkle Hashed for Upload {0}",isLarge, fileInfo.Name))\r
                     {\r
                         //TODO: Load the stored treehash if appropriate\r
                         //TODO: WHO updates LastMD5?\r
@@ -138,7 +139,7 @@ namespace Pithos.Core.Agents
                                 //If this is a read-only file, do not upload changes\r
                                 if ( !cloudInfo.IsWritable(action.AccountInfo.UserName) ||\r
                                     //If the file is new, but we can't upload it\r
-                                    (!cloudInfo.Exists && !client.CanUpload(account, cloudFile)) )\r
+                                    (!cloudInfo.Exists && !await client.CanUpload(account, cloudFile)) )\r
                                 {\r
                                     MakeFileReadOnly(fullFileName);\r
                                     StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal, "");\r
@@ -177,9 +178,9 @@ namespace Pithos.Core.Agents
 \r
                                     string topHash;\r
                                     TreeHash treeHash;\r
+                                    isLarge=(fileInfo as FileInfo).NullSafe(f => f.Length) >= action.AccountInfo.BlockSize;\r
                                     using (\r
-                                        StatusNotification.GetNotifier("Hashing {0} for Upload", "Finished hashing {0}",\r
-                                                                       fileInfo.Name))\r
+                                        StatusNotification.GetNotifier("Hashing {0} for Upload", "Finished hashing {0}",isLarge,fileInfo.Name))\r
                                     {\r
                                         treeHash = localTreeHash ?? action.TreeHash.Value;\r
                                         topHash = treeHash.TopHash.ToHashString();\r
index ce2705e..1f29ad7 100644 (file)
@@ -58,7 +58,7 @@ namespace Pithos.Core
         void SetPithosStatus(PithosStatus status);\r
         void SetPithosStatus(PithosStatus localSyncing, string format);\r
         //Notifier GetNotifier(Notification startNotification, Notification endNotification);\r
-        Notifier GetNotifier(string startMessage, string endMessage,params object[] args);\r
+        Notifier GetNotifier(string startMessage, string endMessage,bool isActive=true,params object[] args);\r
     }\r
 \r
     public class Notification\r
index a131aba..767166f 100644 (file)
       <HintPath>..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>\r
     </Reference>\r
     <Reference Include="System.ServiceModel" />\r
-    <Reference Include="System.Threading.Tasks.Dataflow">\r
-      <HintPath>..\Libraries\System.Threading.Tasks.Dataflow.dll</HintPath>\r
+    <Reference Include="System.Threading.Tasks.Dataflow, Version=0.0.4098.29463, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">\r
+      <SpecificVersion>False</SpecificVersion>\r
+      <HintPath>bin\x86\Debug\System.Threading.Tasks.Dataflow.dll</HintPath>\r
     </Reference>\r
     <Reference Include="System.Transactions" />\r
     <Reference Include="System.Xml.Linq" />\r
index 87aa5e4..cef59f5 100644 (file)
@@ -994,7 +994,7 @@ namespace Pithos.Network
                 var targetUri = GetTargetUri(account).Combine(container).Combine(objectName);\r
                 try\r
                 {\r
-                    using (var response = await _baseHttpClient.HeadAsyncWithRetries(targetUri, 3))\r
+                    using (var response = await _baseHttpClient.HeadAsyncWithRetries(targetUri, 3,true))\r
                     {\r
                         switch (response.StatusCode)\r
                         {\r
@@ -1016,7 +1016,7 @@ namespace Pithos.Network
                                                    Account = account,\r
                                                    Container = container,\r
                                                    Name = objectName,\r
-                                                   ETag = response.Headers.ETag.Tag,\r
+                                                   ETag = response.Headers.ETag.NullSafe(e=>e.Tag),\r
                                                    UUID = response.Headers.GetFirstValue("X-Object-UUID"),\r
                                                    X_Object_Hash = response.Headers.GetFirstValue("X-Object-Hash"),\r
                                                    Content_Type = response.Headers.GetFirstValue("Content-Type"),\r
@@ -1027,7 +1027,7 @@ namespace Pithos.Network
                                                    ContentEncoding =\r
                                                        response.Content.Headers.ContentEncoding.FirstOrDefault(),\r
                                                    ContendDisposition =\r
-                                                       response.Content.Headers.ContentDisposition.ToString(),\r
+                                                       response.Content.Headers.ContentDisposition.NullSafe(c=>c.ToString()),\r
                                                    Manifest = response.Headers.GetFirstValue("X-Object-Manifest"),\r
                                                    PublicUrl = response.Headers.GetFirstValue("X-Object-Public"),\r
                                                    StorageUri = StorageUrl,\r
@@ -1482,7 +1482,7 @@ namespace Pithos.Network
                 });\r
 \r
 \r
-            using (var response = await _baseHttpClientNoTimeout.SendAsyncWithRetries(message, 3, HttpCompletionOption.ResponseHeadersRead,\r
+            using (var response = await _baseHttpClientNoTimeout.SendAsyncWithRetries(message, 3, false,HttpCompletionOption.ResponseHeadersRead,\r
                                                           cancellationToken).ConfigureAwait(false))\r
             using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))\r
             using(var targetStream=new MemoryStream())\r
@@ -1557,7 +1557,7 @@ namespace Pithos.Network
                 message.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(@"application/octet-stream");\r
 \r
                 //Send the block\r
-                using (var response = await _baseHttpClientNoTimeout.SendAsyncWithRetries(message, 3,HttpCompletionOption.ResponseContentRead,token).ConfigureAwait(false))\r
+                using (var response = await _baseHttpClientNoTimeout.SendAsyncWithRetries(message, 3,false,HttpCompletionOption.ResponseContentRead,token).ConfigureAwait(false))\r
                 {                    \r
                     Log.InfoFormat("[BLOCK POST PROGRESS] Completed ");\r
                     response.EnsureSuccessStatusCode();\r
@@ -1729,7 +1729,7 @@ namespace Pithos.Network
             }\r
         }\r
 \r
-        public void DeleteObject(string account, Uri sourceContainer, Uri objectName, bool isDirectory)\r
+        public async Task DeleteObject(string account, Uri sourceContainer, Uri objectName, bool isDirectory)\r
         {\r
             if (sourceContainer == null)\r
                 throw new ArgumentNullException("sourceContainer", "The sourceContainer property can't be empty");\r
@@ -1741,11 +1741,53 @@ namespace Pithos.Network
                 throw new ArgumentException("The objectName must be relative","objectName");\r
             Contract.EndContractBlock();\r
 \r
+\r
+\r
+            var sourceUri = new Uri(String.Format("/{0}/{1}", sourceContainer, objectName),UriKind.Relative);\r
+\r
+            \r
+            if (objectName.OriginalString.EndsWith(".ignore"))\r
+                using(var response = await _baseHttpClient.DeleteAsync(sourceUri)){}\r
+            else\r
+            {\r
+                var relativeUri = new Uri(String.Format("{0}/{1}", FolderConstants.TrashContainer, objectName),\r
+                                                UriKind.Relative);\r
+\r
+/*\r
+                var relativeUri = isDirectory\r
+                                      ? new Uri(\r
+                                            String.Format("{0}/{1}?delimiter=/", FolderConstants.TrashContainer,\r
+                                                          objectName), UriKind.Relative)\r
+                                      : new Uri(String.Format("{0}/{1}", FolderConstants.TrashContainer, objectName),\r
+                                                UriKind.Relative);\r
+\r
+*/\r
+                var targetUri = GetTargetUri(account).Combine(relativeUri);\r
+\r
+\r
+                var message = new HttpRequestMessage(HttpMethod.Put, targetUri);\r
+                message.Headers.Add("X-Move-From", sourceUri.ToString());\r
+\r
+                Log.InfoFormat("[TRASH] [{0}] to [{1}]", sourceUri, targetUri);\r
+                using (var response = await _baseHttpClient.SendAsyncWithRetries(message, 3))\r
+                {\r
+                    var expectedCodes = new[]\r
+                                            {\r
+                                                HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created,\r
+                                                HttpStatusCode.NotFound\r
+                                            };\r
+                    if (!expectedCodes.Contains(response.StatusCode))\r
+                        throw CreateWebException("DeleteObject", response.StatusCode);\r
+                }\r
+            }\r
+/*\r
+            \r
+\r
             var targetUrl = FolderConstants.TrashContainer + "/" + objectName;\r
 /*\r
             if (isDirectory)\r
                 targetUrl = targetUrl + "?delimiter=/";\r
-*/\r
+#1#\r
 \r
             var sourceUrl = String.Format("/{0}/{1}", sourceContainer, objectName);\r
 \r
@@ -1763,6 +1805,7 @@ namespace Pithos.Network
                 if (!expectedCodes.Contains(client.StatusCode))\r
                     throw CreateWebException("DeleteObject", client.StatusCode);\r
             }\r
+*/\r
         }\r
 \r
       \r
@@ -1772,39 +1815,34 @@ namespace Pithos.Network
         }\r
 \r
 \r
-        public bool CanUpload(string account, ObjectInfo cloudFile)\r
+        public async Task<bool> CanUpload(string account, ObjectInfo cloudFile)\r
         {\r
             Contract.Requires(!String.IsNullOrWhiteSpace(account));\r
             Contract.Requires(cloudFile!=null);\r
 \r
-            using (var client = new RestClient(_baseClient))\r
-            {\r
-                if (!String.IsNullOrWhiteSpace(account))\r
-                    client.BaseAddress = GetAccountUrl(account);\r
-\r
-\r
                 var parts = cloudFile.Name.ToString().Split('/');\r
                 var folder = String.Join("/", parts,0,parts.Length-1);\r
 \r
                 var fileName = String.Format("{0}/{1}.pithos.ignore", folder, Guid.NewGuid());\r
                 var fileUri=fileName.ToEscapedUri();                                            \r
 \r
-                client.Parameters.Clear();\r
                 try\r
                 {\r
                     var relativeUri = cloudFile.Container.Combine(fileUri);\r
-                    client.PutWithRetry(relativeUri, 3, @"application/octet-stream");\r
-\r
+                    var targetUri = GetTargetUri(account).Combine(relativeUri);\r
+                    var message = new HttpRequestMessage(HttpMethod.Put, targetUri);\r
+                    message.Content.Headers.ContentType =new MediaTypeHeaderValue("application/octet-stream");\r
+                    var response=await _baseHttpClient.SendAsyncWithRetries(message, 3);                    \r
                     var expectedCodes = new[] { HttpStatusCode.OK, HttpStatusCode.NoContent, HttpStatusCode.Created};\r
-                    var result=(expectedCodes.Contains(client.StatusCode));\r
-                    DeleteObject(account, cloudFile.Container, fileUri, cloudFile.IsDirectory);\r
+                    var result=(expectedCodes.Contains(response.StatusCode));\r
+                    await DeleteObject(account, cloudFile.Container, fileUri, cloudFile.IsDirectory);\r
                     return result;\r
                 }\r
                 catch\r
                 {\r
                     return false;\r
                 }\r
-            }\r
+            \r
         }\r
 \r
         ~CloudFilesClient()\r
index cab3eb7..8f5c247 100644 (file)
@@ -80,7 +80,7 @@ namespace Pithos.Network
         #region Object operations        \r
         Task GetObject(string account, Uri container, Uri objectName, string fileName, CancellationToken cancellationToken);\r
         Task PutObject(string account, Uri container, Uri objectName, string fileName, string hash = null, string contentType = "application/octet-stream");\r
-        void DeleteObject(string account, Uri container, Uri objectName, bool isDirectory);\r
+        Task DeleteObject(string account, Uri container, Uri objectName, bool isDirectory);\r
         //void DeleteObject(string container, string objectName, string account = null);\r
         void MoveObject(string account, Uri sourceContainer, Uri oldObjectName, Uri targetContainer, Uri newObjectName);\r
         bool ObjectExists(string account, Uri container, Uri objectName);\r
@@ -298,7 +298,7 @@ namespace Pithos.Network
             return default(Task);\r
         }\r
 \r
-        public void DeleteObject(string account, Uri container, Uri objectName, bool isDirectory)\r
+        public Task DeleteObject(string account, Uri container, Uri objectName, bool isDirectory)\r
         {\r
             \r
             Contract.Requires(!String.IsNullOrWhiteSpace(Token));\r
@@ -307,6 +307,8 @@ namespace Pithos.Network
             Contract.Requires(!container.IsAbsoluteUri);\r
             Contract.Requires(objectName != null);\r
             Contract.Requires(!objectName.IsAbsoluteUri);\r
+\r
+            return default(Task);\r
         }\r
 \r
         public void MoveObject(string account, Uri sourceContainer, Uri oldObjectName, Uri targetContainer, Uri newObjectName)\r
index a4a6bf8..6fbf59e 100644 (file)
       <HintPath>..\packages\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll</HintPath>\r
     </Reference>\r
     <Reference Include="System.ServiceModel" />\r
+    <Reference Include="System.ServiceModel.Channels" />\r
     <Reference Include="System.Threading.Tasks.Dataflow">\r
       <HintPath>..\Libraries\System.Threading.Tasks.Dataflow.dll</HintPath>\r
     </Reference>\r
index ca78e1d..a1fb7d8 100644 (file)
@@ -12,6 +12,7 @@ using System.IO;
 using System.Threading;\r
 using System.Threading.Tasks;\r
 using log4net;\r
+using System.ServiceModel.Channels;\r
 \r
 namespace Pithos.Network\r
 {\r
@@ -185,14 +186,14 @@ namespace Pithos.Network
 \r
         }\r
 \r
-        public static Task<HttpResponseMessage> HeadAsyncWithRetries(this HttpClient client, Uri requestUri, int retries)\r
+        public static Task<HttpResponseMessage> HeadAsyncWithRetries(this HttpClient client, Uri requestUri, int retries,bool acceptNotFound=false)\r
         {\r
-            return client.HeadAsyncWithRetries(requestUri, retries, HttpCompletionOption.ResponseContentRead, CancellationToken.None);\r
+            return client.HeadAsyncWithRetries(requestUri, retries, acceptNotFound,HttpCompletionOption.ResponseContentRead, CancellationToken.None);\r
         }\r
 \r
-        public static Task<HttpResponseMessage> HeadAsyncWithRetries(this HttpClient client, Uri requestUri, int retries, HttpCompletionOption completionOption, CancellationToken cancellationToken)\r
+        public static Task<HttpResponseMessage> HeadAsyncWithRetries(this HttpClient client, Uri requestUri, int retries, bool acceptNotFound,HttpCompletionOption completionOption, CancellationToken cancellationToken)\r
         {\r
-            return client.SendAsyncWithRetries(new HttpRequestMessage(HttpMethod.Head, requestUri), retries, completionOption, cancellationToken);\r
+            return client.SendAsyncWithRetries(new HttpRequestMessage(HttpMethod.Head, requestUri), retries, acceptNotFound,completionOption, cancellationToken);\r
         }\r
 \r
         public static Task<HttpResponseMessage> GetAsyncWithRetries(this HttpClient client, Uri requestUri, int retries)\r
@@ -202,26 +203,34 @@ namespace Pithos.Network
 \r
         public static Task<HttpResponseMessage> GetAsyncWithRetries(this HttpClient client, Uri requestUri, int retries, HttpCompletionOption completionOption, CancellationToken cancellationToken)\r
         {\r
-            return client.SendAsyncWithRetries(new HttpRequestMessage(HttpMethod.Get, requestUri), retries, completionOption, cancellationToken);\r
+            return client.SendAsyncWithRetries(new HttpRequestMessage(HttpMethod.Get, requestUri), retries, false,completionOption, cancellationToken);\r
         }\r
 \r
 \r
         public static Task<HttpResponseMessage> SendAsyncWithRetries(this HttpClient client,HttpRequestMessage message, int retries)\r
         {\r
-            return client.SendAsyncWithRetries(message, retries, HttpCompletionOption.ResponseContentRead, CancellationToken.None);\r
+            return client.SendAsyncWithRetries(message, retries,false, HttpCompletionOption.ResponseContentRead, CancellationToken.None);\r
         }\r
 \r
-        public static async Task<HttpResponseMessage> SendAsyncWithRetries(this HttpClient client,HttpRequestMessage message, int retries,HttpCompletionOption completionOption, CancellationToken cancellationToken)\r
+        public static async Task<HttpResponseMessage> SendAsyncWithRetries(this HttpClient client,HttpRequestMessage message, int retries,bool acceptNotFound,HttpCompletionOption completionOption, CancellationToken cancellationToken)\r
         {\r
             var waitTime = TimeSpan.FromSeconds(10);\r
-            var acceptedCodes = new[] { HttpStatusCode.Moved, HttpStatusCode.MovedPermanently, HttpStatusCode.Found, HttpStatusCode.Redirect,HttpStatusCode.SeeOther,\r
+            var acceptedCodes =acceptNotFound\r
+                ? new[] {HttpStatusCode.NotFound, HttpStatusCode.Moved, HttpStatusCode.MovedPermanently, HttpStatusCode.Found, HttpStatusCode.Redirect,HttpStatusCode.SeeOther,\r
+                HttpStatusCode.RedirectMethod,HttpStatusCode.NotModified,HttpStatusCode.TemporaryRedirect,HttpStatusCode.RedirectKeepVerb,HttpStatusCode.Conflict}\r
+                : new[] { HttpStatusCode.Moved, HttpStatusCode.MovedPermanently, HttpStatusCode.Found, HttpStatusCode.Redirect,HttpStatusCode.SeeOther,\r
                 HttpStatusCode.RedirectMethod,HttpStatusCode.NotModified,HttpStatusCode.TemporaryRedirect,HttpStatusCode.RedirectKeepVerb,HttpStatusCode.Conflict};\r
+            \r
+                \r
             while (retries > 0)\r
             {\r
                 var timedOut = false;\r
                 if (Log.IsDebugEnabled)\r
                     Log.DebugFormat("[REQUEST] {0}", message);\r
                 HttpResponseMessage result=null;\r
+                \r
+                \r
+                \r
                 try\r
                 {\r
                     result = await client.SendAsync(message, completionOption, cancellationToken).ConfigureAwait(false);\r
@@ -234,6 +243,20 @@ namespace Pithos.Network
                     if (Log.IsDebugEnabled)\r
                         Log.DebugFormat("[RESPONSE] [{0}]:[{1}] FAIL WITH TIMEOUT", message.Method, message.RequestUri);\r
                 }\r
+                catch(TaskCanceledException exc)\r
+                {\r
+                    //If the task was cancelled due to a timeout, retry it\r
+                    if (!exc.CancellationToken.IsCancellationRequested)\r
+                    {\r
+                        timedOut = true;\r
+                        if (Log.IsDebugEnabled)\r
+                            Log.DebugFormat("[RESPONSE] [{0}]:[{1}] FAIL WITH TIMEOUT", message.Method, message.RequestUri);\r
+                    }\r
+                    else\r
+                    {\r
+                        throw;\r
+                    }\r
+                }\r
                 catch (Exception exc)\r
                 {\r
                     Log.FatalFormat("Unexpected error while sending:\n{0}\n{1}", message, exc);\r