Revision 2341c603 trunk/Pithos.Core/Agents/NetworkAgent.cs

b/trunk/Pithos.Core/Agents/NetworkAgent.cs
46 46
using System.Diagnostics;
47 47
using System.Diagnostics.Contracts;
48 48
using System.IO;
49
using System.Linq;
49 50
using System.Net;
50 51
using System.Reflection;
51 52
using System.Threading;
......
87 88
        [System.ComponentModel.Composition.Import]
88 89
        public IPithosSettings Settings { get; set; }
89 90

  
91
        private Uploader _uploader;
92

  
90 93
        [System.ComponentModel.Composition.Import]
91
        public Uploader Uploader { get; set; }
94
        public Uploader Uploader
95
        {
96
            get { return _uploader; }
97
            set
98
            {
99
                _uploader = value;
100
                _uploader.UnpauseEvent = _unPauseEvent;                
101
            }
102
        }
103

  
104
        private Downloader _downloader;
92 105

  
93 106
        [System.ComponentModel.Composition.Import]
94
        public Downloader Downloader { get; set; }
107
        public Downloader Downloader
108
        {
109
            get { return _downloader; }
110
            set
111
            {
112
                _downloader = value;
113
                _downloader.UnpauseEvent = _unPauseEvent;
114
            }
115
        }
95 116

  
117
        [System.ComponentModel.Composition.Import]
118
        public Selectives Selectives { get; set; }
119
        
96 120
        //The Proceed signals the poll agent that it can proceed with polling. 
97 121
        //Essentially it stops the poll agent to give priority to the network agent
98 122
        //Initially the event is signalled because we don't need to pause
99 123
        private readonly AsyncManualResetEvent _proceedEvent = new AsyncManualResetEvent(true);
124
        private Agents.Selectives _selectives;
125
        private bool _pause;
100 126

  
101 127
        public AsyncManualResetEvent ProceedEvent
102 128
        {
103 129
            get { return _proceedEvent; }
104 130
        }
105 131

  
132
        private readonly AsyncManualResetEvent _unPauseEvent = new AsyncManualResetEvent(true);
133

  
134
        private CancellationTokenSource _currentOperationCancellation=new CancellationTokenSource();
135

  
136
        public void CancelCurrentOperation()
137
        {
138
            //What does it mean to cancel the current upload/download?
139
            //Obviously, the current operation will be cancelled by throwing
140
            //a cancellation exception.
141
            //
142
            //The default behavior is to retry any operations that throw.
143
            //Obviously this is not what we want in this situation.
144
            //The cancelled operation should NOT bea retried. 
145
            //
146
            //This can be done by catching the cancellation exception
147
            //and avoiding the retry.
148
            //
149

  
150
            //Have to reset the cancellation source - it is not possible to reset the source
151
            //Have to prevent a case where an operation requests a token from the old source
152
            var oldSource = Interlocked.Exchange(ref _currentOperationCancellation, new CancellationTokenSource());
153
            oldSource.Cancel();
154
            
155
        }
106 156

  
107 157
        public void Start()
108 158
        {
......
118 168
                loop = () =>
119 169
                {
120 170
                    DeleteAgent.ProceedEvent.Wait();
171
                    _unPauseEvent.Wait();
121 172
                    var message = inbox.Receive();
122 173
                    var process=message.Then(Process,inbox.CancellationToken);
123 174
                    inbox.LoopAsync(process, loop);
......
168 219
                        {
169 220
                            case CloudActionType.UploadUnconditional:
170 221
                                //Abort if the file was deleted before we reached this point
171
                                await Uploader.UploadCloudFile(action);
222
                                await Uploader.UploadCloudFile(action,CurrentOperationCancelToken);
172 223
                                break;
173 224
                            case CloudActionType.DownloadUnconditional:
174
                                await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath);
225
                                await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath, CurrentOperationCancelToken);
175 226
                                break;
176 227
                            case CloudActionType.RenameCloud:
177 228
                                var moveAction = (CloudMoveAction)action;
......
183 234
                            case CloudActionType.MustSynch:
184 235
                                if (!File.Exists(downloadPath) && !Directory.Exists(downloadPath))
185 236
                                {
186
                                    await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath);
237
                                    await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath, CurrentOperationCancelToken);
187 238
                                }
188 239
                                else
189 240
                                {
......
210 261
                    }
211 262
                }
212 263
*/
213
                catch (OperationCanceledException)
214
                {
215
                    throw;
264
                catch (OperationCanceledException ex)
265
                {                    
266
                    Log.WarnFormat("Cancelling [{0}]",ex);
216 267
                }
217 268
                catch (DirectoryNotFoundException)
218 269
                {
......
244 295
            }
245 296
        }
246 297

  
298
        private CancellationToken CurrentOperationCancelToken
299
        {
300
            get { return _currentOperationCancellation.Token; }
301
        }
302

  
247 303

  
248 304
        private void UpdateStatus(PithosStatus status)
249 305
        {
......
358 414
                // If the previous tophash matches the local tophash, the file was only changed on the server. 
359 415
                if (localHash == previousCloudHash)
360 416
                {
361
                    await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath);
417
                    await Downloader.DownloadCloudFile(accountInfo, cloudFile, downloadPath, CurrentOperationCancelToken);
362 418
                }
363 419
                else
364 420
                {
......
439 495
            get { return _agent.CancellationToken; }
440 496
        }
441 497

  
498
        public bool Pause
499
        {
500
            get {
501
                return _pause;
502
            }
503
            set {
504
                _pause = value;
505
                if (_pause)
506
                    _unPauseEvent.Reset();
507
                else
508
                {
509
                    _unPauseEvent.Set();
510
                }
511
            }
512
        }
442 513

  
443 514

  
444 515
        private void RenameCloudFile(AccountInfo accountInfo,CloudMoveAction action)
......
492 563
        }
493 564

  
494 565

  
566
        
495 567

  
496 568
    }
497 569

  

Also available in: Unified diff