+ /// <summary>
+ /// Processes cloud delete actions
+ /// </summary>
+ /// <param name="action">The delete action to execute</param>
+ /// <returns></returns>
+ /// <remarks>
+ /// When a file/folder is deleted locally, we must delete it ASAP from the server and block any download
+ /// operations that may be in progress.
+ /// <para>
+ /// A separate agent is used to process deletes because the main agent may be busy with a long operation.
+ /// </para>
+ /// </remarks>
+ private async Task ProcessDelete(CloudDeleteAction action)
+ {
+ if (action == null)
+ throw new ArgumentNullException("action");
+ if (action.AccountInfo==null)
+ throw new ArgumentException("The action.AccountInfo is empty","action");
+ Contract.EndContractBlock();
+
+ var accountInfo = action.AccountInfo;
+
+ using (log4net.ThreadContext.Stacks["NETWORK"].Push("PROCESS"))
+ {
+ Log.InfoFormat("[ACTION] Start Processing {0}", action);
+
+ var cloudFile = action.CloudFile;
+
+ try
+ {
+ //Acquire a lock on the deleted file to prevent uploading/downloading operations from the normal
+ //agent
+ using (var gate = NetworkGate.Acquire(action.LocalFile.FullName, NetworkOperation.Deleting))
+ {
+
+ //Add the file URL to the deleted files list
+ var key = GetFileKey(action.CloudFile);
+ _deletedFiles[key] = DateTime.Now;
+
+ _pauseAgent.Reset();
+ // and then delete the file from the server
+ DeleteCloudFile(accountInfo, cloudFile);
+
+ Log.InfoFormat("[ACTION] End Delete {0}:{1}->{2}", action.Action, action.LocalFile,
+ action.CloudFile.Name);
+ }
+ }
+ catch (WebException exc)
+ {
+ Log.ErrorFormat("[WEB ERROR] {0} : {1} -> {2} due to exception\r\n{3}", action.Action, action.LocalFile, action.CloudFile, exc);
+ }
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
+ catch (DirectoryNotFoundException)
+ {
+ Log.ErrorFormat("{0} : {1} -> {2} failed because the directory was not found.\n Rescheduling a delete",
+ action.Action, action.LocalFile, action.CloudFile);
+ //Repost a delete action for the missing file
+ _deleteAgent.Post(action);
+ }
+ catch (FileNotFoundException)
+ {
+ Log.ErrorFormat("{0} : {1} -> {2} failed because the file was not found.\n Rescheduling a delete",
+ action.Action, action.LocalFile, action.CloudFile);
+ //Post a delete action for the missing file
+ _deleteAgent.Post(action);
+ }
+ catch (Exception exc)
+ {
+ Log.ErrorFormat("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
+ action.Action, action.LocalFile, action.CloudFile, exc);
+
+ _deleteAgent.Post(action);
+ }
+ finally
+ {
+ //Set the event when all delete actions are processed
+ if (_deleteAgent.InputCount == 0)
+ _pauseAgent.Set();
+
+ }
+ }
+ }
+
+ private static string GetFileKey(ObjectInfo info)
+ {
+ var key = String.Format("{0}/{1}/{2}", info.Account, info.Container,info.Name);
+ return key;
+ }
+