Revision 039a89e5 trunk/Pithos.Core/Agents/NetworkAgent.cs
b/trunk/Pithos.Core/Agents/NetworkAgent.cs | ||
---|---|---|
60 | 60 |
|
61 | 61 |
//A separate agent is used to execute delete actions immediatelly; |
62 | 62 |
private Agent<CloudDeleteAction> _deleteAgent; |
63 |
|
|
63 |
ConcurrentDictionary<string,DateTime> _deletedFiles=new ConcurrentDictionary<string, DateTime>(); |
|
64 | 64 |
|
65 | 65 |
[System.ComponentModel.Composition.Import] |
66 | 66 |
public IStatusKeeper StatusKeeper { get; set; } |
... | ... | |
123 | 123 |
switch (action.Action) |
124 | 124 |
{ |
125 | 125 |
case CloudActionType.UploadUnconditional: |
126 |
await UploadCloudFile(action); |
|
126 |
//Abort if the file was deleted before we reached this point |
|
127 |
if (!IsDeletedFile(action)) |
|
128 |
await UploadCloudFile(action); |
|
127 | 129 |
break; |
128 | 130 |
case CloudActionType.DownloadUnconditional: |
129 |
|
|
130 |
await DownloadCloudFile(accountInfo, cloudFile, downloadPath); |
|
131 |
if (!IsDeletedFile(action)) |
|
132 |
await DownloadCloudFile(accountInfo, cloudFile, downloadPath);
|
|
131 | 133 |
break; |
132 | 134 |
case CloudActionType.DeleteCloud: |
133 | 135 |
//Redirect deletes to the delete agent |
... | ... | |
135 | 137 |
break; |
136 | 138 |
case CloudActionType.RenameCloud: |
137 | 139 |
var moveAction = (CloudMoveAction)action; |
138 |
RenameCloudFile(accountInfo, moveAction); |
|
140 |
if (!IsDeletedFile(action)) |
|
141 |
RenameCloudFile(accountInfo, moveAction); |
|
139 | 142 |
break; |
140 | 143 |
case CloudActionType.MustSynch: |
141 | 144 |
if (!File.Exists(downloadPath) && !Directory.Exists(downloadPath)) |
142 | 145 |
{ |
143 |
await DownloadCloudFile(accountInfo, cloudFile, downloadPath); |
|
146 |
if (!IsDeletedFile(action)) |
|
147 |
await DownloadCloudFile(accountInfo, cloudFile, downloadPath); |
|
144 | 148 |
} |
145 | 149 |
else |
146 | 150 |
{ |
147 |
await SyncFiles(accountInfo, action); |
|
151 |
if (!IsDeletedFile(action)) |
|
152 |
await SyncFiles(accountInfo, action); |
|
148 | 153 |
} |
149 | 154 |
break; |
150 | 155 |
} |
... | ... | |
217 | 222 |
//agent |
218 | 223 |
using (var gate = NetworkGate.Acquire(action.LocalFile.FullName, NetworkOperation.Deleting)) |
219 | 224 |
{ |
220 |
// Remove any related actions from the normal agent |
|
221 |
_agent.Remove(queuedAction => |
|
222 |
queuedAction.CloudFile.Container == action.CloudFile.Container && |
|
223 |
queuedAction.CloudFile.Name == action.CloudFile.Name); |
|
225 |
|
|
226 |
//Add the file URL to the deleted files list |
|
227 |
var key = GetFileKey(action.CloudFile); |
|
228 |
_deletedFiles[key]=DateTime.Now; |
|
229 |
|
|
224 | 230 |
// and then delete the file from the server |
225 | 231 |
DeleteCloudFile(accountInfo, cloudFile); |
226 | 232 |
Log.InfoFormat("[ACTION] End Delete {0}:{1}->{2}", action.Action, action.LocalFile, |
... | ... | |
259 | 265 |
} |
260 | 266 |
} |
261 | 267 |
|
268 |
private static string GetFileKey(ObjectInfo info) |
|
269 |
{ |
|
270 |
var key = String.Format("{0}/{1}/{2}", info.Account, info.Container,info.Name); |
|
271 |
return key; |
|
272 |
} |
|
273 |
|
|
262 | 274 |
private async Task SyncFiles(AccountInfo accountInfo,CloudAction action) |
263 | 275 |
{ |
264 | 276 |
if (accountInfo == null) |
... | ... | |
551 | 563 |
continue; |
552 | 564 |
using (new SessionScope(FlushAction.Never)) |
553 | 565 |
{ |
554 |
var state = FileState.FindByFilePath(localFile.FullName); |
|
566 |
var state = StatusKeeper.GetStateByFilePath(localFile.FullName); |
|
567 |
//FileState.FindByFilePath(localFile.FullName); |
|
555 | 568 |
//Common files should be checked on a per-case basis to detect differences, which is newer |
556 | 569 |
|
557 | 570 |
yield return new CloudAction(accountInfo, CloudActionType.MustSynch, |
... | ... | |
695 | 708 |
if (cloudFile.Name.EndsWith(".ignore", StringComparison.InvariantCultureIgnoreCase)) |
696 | 709 |
return; |
697 | 710 |
|
711 |
|
|
698 | 712 |
//Are we already downloading or uploading the file? |
699 | 713 |
using (var gate=NetworkGate.Acquire(localPath, NetworkOperation.Downloading)) |
700 | 714 |
{ |
... | ... | |
884 | 898 |
|
885 | 899 |
if (fileInfo.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)) |
886 | 900 |
return; |
887 |
|
|
901 |
|
|
888 | 902 |
var relativePath = fileInfo.AsRelativeTo(accountInfo.AccountPath); |
889 | 903 |
if (relativePath.StartsWith(FolderConstants.OthersFolder)) |
890 | 904 |
{ |
... | ... | |
994 | 1008 |
|
995 | 1009 |
} |
996 | 1010 |
|
1011 |
private bool IsDeletedFile(CloudAction action) |
|
1012 |
{ |
|
1013 |
var key = GetFileKey(action.CloudFile); |
|
1014 |
DateTime entryDate; |
|
1015 |
if (_deletedFiles.TryGetValue(key, out entryDate)) |
|
1016 |
{ |
|
1017 |
//If the delete entry was created after this action, abort the action |
|
1018 |
if (entryDate > action.Created) |
|
1019 |
return true; |
|
1020 |
//Otherwise, remove the stale entry |
|
1021 |
_deletedFiles.TryRemove(key, out entryDate); |
|
1022 |
} |
|
1023 |
return false; |
|
1024 |
} |
|
1025 |
|
|
997 | 1026 |
private bool HandleUploadWebException(CloudAction action, WebException exc) |
998 | 1027 |
{ |
999 | 1028 |
var response = exc.Response as HttpWebResponse; |
Also available in: Unified diff