root / trunk / Pithos.Core / PithosMonitor.cs @ 3c43ec9b
History | View | Annotate | Download (26.9 kB)
1 | d78cbf09 | Panagiotis Kanavos | using System; |
---|---|---|---|
2 | d78cbf09 | Panagiotis Kanavos | using System.Collections.Concurrent; |
3 | d78cbf09 | Panagiotis Kanavos | using System.Collections.Generic; |
4 | d78cbf09 | Panagiotis Kanavos | using System.ComponentModel.Composition; |
5 | d78cbf09 | Panagiotis Kanavos | using System.Diagnostics; |
6 | d78cbf09 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
7 | d78cbf09 | Panagiotis Kanavos | using System.IO; |
8 | d78cbf09 | Panagiotis Kanavos | using System.Linq; |
9 | 29672672 | Panagiotis Kanavos | using System.Net.NetworkInformation; |
10 | d78cbf09 | Panagiotis Kanavos | using System.Security.Cryptography; |
11 | 5bcf6d70 | Panagiotis Kanavos | using System.ServiceModel.Description; |
12 | d78cbf09 | Panagiotis Kanavos | using System.Text; |
13 | d78cbf09 | Panagiotis Kanavos | using System.Threading; |
14 | d78cbf09 | Panagiotis Kanavos | using System.Threading.Tasks; |
15 | 0eea575a | Panagiotis Kanavos | using Castle.ActiveRecord.Queries; |
16 | 637bc368 | Panagiotis Kanavos | using Microsoft.WindowsAPICodePack.Net; |
17 | d78cbf09 | Panagiotis Kanavos | using Pithos.Interfaces; |
18 | eeee29e3 | Panagiotis Kanavos | using System.ServiceModel; |
19 | d78cbf09 | Panagiotis Kanavos | |
20 | d78cbf09 | Panagiotis Kanavos | namespace Pithos.Core |
21 | d78cbf09 | Panagiotis Kanavos | { |
22 | d78cbf09 | Panagiotis Kanavos | [Export(typeof(PithosMonitor))] |
23 | d78cbf09 | Panagiotis Kanavos | public class PithosMonitor:IDisposable |
24 | d78cbf09 | Panagiotis Kanavos | { |
25 | 3c43ec9b | Panagiotis Kanavos | private const string PithosContainer = "pithos"; |
26 | 3c43ec9b | Panagiotis Kanavos | private const string TrashContainer = "trash"; |
27 | 3c43ec9b | Panagiotis Kanavos | |
28 | d78cbf09 | Panagiotis Kanavos | [Import] |
29 | d78cbf09 | Panagiotis Kanavos | public IPithosSettings Settings{get;set;} |
30 | d78cbf09 | Panagiotis Kanavos | |
31 | d78cbf09 | Panagiotis Kanavos | [Import] |
32 | d78cbf09 | Panagiotis Kanavos | public IStatusKeeper StatusKeeper { get; set; } |
33 | d78cbf09 | Panagiotis Kanavos | |
34 | d78cbf09 | Panagiotis Kanavos | [Import] |
35 | d78cbf09 | Panagiotis Kanavos | public IPithosWorkflow Workflow { get; set; } |
36 | d78cbf09 | Panagiotis Kanavos | |
37 | d78cbf09 | Panagiotis Kanavos | [Import] |
38 | d78cbf09 | Panagiotis Kanavos | public ICloudClient CloudClient { get; set; } |
39 | d78cbf09 | Panagiotis Kanavos | |
40 | d78cbf09 | Panagiotis Kanavos | [Import] |
41 | d78cbf09 | Panagiotis Kanavos | public ICloudClient CloudListeningClient { get; set; } |
42 | d78cbf09 | Panagiotis Kanavos | |
43 | 0eea575a | Panagiotis Kanavos | public string UserName { get; set; } |
44 | 0eea575a | Panagiotis Kanavos | public string ApiKey { get; set; } |
45 | 0eea575a | Panagiotis Kanavos | |
46 | eeee29e3 | Panagiotis Kanavos | private ServiceHost _statusService { get; set; } |
47 | eeee29e3 | Panagiotis Kanavos | |
48 | d78cbf09 | Panagiotis Kanavos | private FileSystemWatcher _watcher; |
49 | d78cbf09 | Panagiotis Kanavos | |
50 | d78cbf09 | Panagiotis Kanavos | public bool Pause |
51 | d78cbf09 | Panagiotis Kanavos | { |
52 | d78cbf09 | Panagiotis Kanavos | get { return _watcher == null || !_watcher.EnableRaisingEvents; } |
53 | d78cbf09 | Panagiotis Kanavos | set |
54 | d78cbf09 | Panagiotis Kanavos | { |
55 | d78cbf09 | Panagiotis Kanavos | if (_watcher!=null) |
56 | 5bcf6d70 | Panagiotis Kanavos | _watcher.EnableRaisingEvents = !value; |
57 | 5bcf6d70 | Panagiotis Kanavos | if (value) |
58 | 5bcf6d70 | Panagiotis Kanavos | { |
59 | 5bcf6d70 | Panagiotis Kanavos | StatusKeeper.SetPithosStatus(PithosStatus.SyncPaused); |
60 | 5bcf6d70 | Panagiotis Kanavos | } |
61 | 5bcf6d70 | Panagiotis Kanavos | else |
62 | 5bcf6d70 | Panagiotis Kanavos | { |
63 | 5bcf6d70 | Panagiotis Kanavos | StatusKeeper.SetPithosStatus(PithosStatus.InSynch); |
64 | 5bcf6d70 | Panagiotis Kanavos | } |
65 | d78cbf09 | Panagiotis Kanavos | } |
66 | d78cbf09 | Panagiotis Kanavos | } |
67 | d78cbf09 | Panagiotis Kanavos | |
68 | 0eea575a | Panagiotis Kanavos | public string RootPath { get; set; } |
69 | 0eea575a | Panagiotis Kanavos | |
70 | d78cbf09 | Panagiotis Kanavos | |
71 | d78cbf09 | Panagiotis Kanavos | CancellationTokenSource _cancellationSource; |
72 | d78cbf09 | Panagiotis Kanavos | |
73 | 29672672 | Panagiotis Kanavos | readonly BlockingCollection<WorkflowState> _fileEvents = new BlockingCollection<WorkflowState>(); |
74 | 29672672 | Panagiotis Kanavos | readonly BlockingCollection<WorkflowState> _uploadEvents = new BlockingCollection<WorkflowState>(); |
75 | d78cbf09 | Panagiotis Kanavos | |
76 | d78cbf09 | Panagiotis Kanavos | |
77 | d78cbf09 | Panagiotis Kanavos | |
78 | d78cbf09 | Panagiotis Kanavos | public void Start() |
79 | d78cbf09 | Panagiotis Kanavos | { |
80 | d78cbf09 | Panagiotis Kanavos | |
81 | d78cbf09 | Panagiotis Kanavos | if (_cancellationSource != null) |
82 | d78cbf09 | Panagiotis Kanavos | { |
83 | d78cbf09 | Panagiotis Kanavos | if (!_cancellationSource.IsCancellationRequested) |
84 | d78cbf09 | Panagiotis Kanavos | return; |
85 | d78cbf09 | Panagiotis Kanavos | } |
86 | 29672672 | Panagiotis Kanavos | _cancellationSource = new CancellationTokenSource(); |
87 | d78cbf09 | Panagiotis Kanavos | |
88 | 5bcf6d70 | Panagiotis Kanavos | var proxyUri = ProxyFromSettings(); |
89 | 5bcf6d70 | Panagiotis Kanavos | CloudClient.Proxy = proxyUri; |
90 | 3c43ec9b | Panagiotis Kanavos | CloudClient.UsePithos = this.UsePithos; |
91 | 3c43ec9b | Panagiotis Kanavos | EnsurePithosContainers(); |
92 | 3c43ec9b | Panagiotis Kanavos | StatusKeeper.StartProcessing(_cancellationSource.Token); |
93 | 0eea575a | Panagiotis Kanavos | IndexLocalFiles(RootPath); |
94 | 0eea575a | Panagiotis Kanavos | StartMonitoringFiles(RootPath); |
95 | d78cbf09 | Panagiotis Kanavos | |
96 | eeee29e3 | Panagiotis Kanavos | StartStatusService(); |
97 | eeee29e3 | Panagiotis Kanavos | |
98 | 29672672 | Panagiotis Kanavos | StartNetwork(); |
99 | 29672672 | Panagiotis Kanavos | } |
100 | 29672672 | Panagiotis Kanavos | |
101 | 3c43ec9b | Panagiotis Kanavos | private void EnsurePithosContainers() |
102 | 3c43ec9b | Panagiotis Kanavos | { |
103 | 3c43ec9b | Panagiotis Kanavos | CloudClient.UsePithos = this.UsePithos; |
104 | 3c43ec9b | Panagiotis Kanavos | CloudClient.Authenticate(UserName, ApiKey); |
105 | 3c43ec9b | Panagiotis Kanavos | |
106 | 3c43ec9b | Panagiotis Kanavos | var pithosContainers = new[] {PithosContainer, TrashContainer}; |
107 | 3c43ec9b | Panagiotis Kanavos | foreach (var container in pithosContainers) |
108 | 3c43ec9b | Panagiotis Kanavos | { |
109 | 3c43ec9b | Panagiotis Kanavos | if (!CloudClient.ContainerExists(container)) |
110 | 3c43ec9b | Panagiotis Kanavos | CloudClient.CreateContainer(container); |
111 | 3c43ec9b | Panagiotis Kanavos | } |
112 | 3c43ec9b | Panagiotis Kanavos | } |
113 | 3c43ec9b | Panagiotis Kanavos | |
114 | 5bcf6d70 | Panagiotis Kanavos | private Uri ProxyFromSettings() |
115 | 5bcf6d70 | Panagiotis Kanavos | { |
116 | 5bcf6d70 | Panagiotis Kanavos | if (Settings.UseManualProxy) |
117 | 5bcf6d70 | Panagiotis Kanavos | { |
118 | 5bcf6d70 | Panagiotis Kanavos | var proxyUri = new UriBuilder |
119 | 5bcf6d70 | Panagiotis Kanavos | { |
120 | 5bcf6d70 | Panagiotis Kanavos | Host = Settings.ProxyServer, |
121 | 5bcf6d70 | Panagiotis Kanavos | Port = Settings.ProxyPort |
122 | 5bcf6d70 | Panagiotis Kanavos | }; |
123 | 5bcf6d70 | Panagiotis Kanavos | if (Settings.ProxyAuthentication) |
124 | 5bcf6d70 | Panagiotis Kanavos | { |
125 | 5bcf6d70 | Panagiotis Kanavos | proxyUri.UserName = Settings.ProxyUsername; |
126 | 5bcf6d70 | Panagiotis Kanavos | proxyUri.Password = Settings.ProxyPassword; |
127 | 5bcf6d70 | Panagiotis Kanavos | } |
128 | 5bcf6d70 | Panagiotis Kanavos | return proxyUri.Uri; |
129 | 5bcf6d70 | Panagiotis Kanavos | } |
130 | 5bcf6d70 | Panagiotis Kanavos | return null; |
131 | 5bcf6d70 | Panagiotis Kanavos | } |
132 | 5bcf6d70 | Panagiotis Kanavos | |
133 | b5061ac8 | Panagiotis Kanavos | private void IndexLocalFiles(string path) |
134 | b5061ac8 | Panagiotis Kanavos | { |
135 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[START] Inxed Local"); |
136 | b5061ac8 | Panagiotis Kanavos | try |
137 | b5061ac8 | Panagiotis Kanavos | { |
138 | b5061ac8 | Panagiotis Kanavos | var files = |
139 | b5061ac8 | Panagiotis Kanavos | from filePath in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).AsParallel() |
140 | b5061ac8 | Panagiotis Kanavos | select filePath; |
141 | b5061ac8 | Panagiotis Kanavos | StatusKeeper.StoreUnversionedFiles(files); |
142 | b5061ac8 | Panagiotis Kanavos | |
143 | 0eea575a | Panagiotis Kanavos | RestartInterruptedFiles(); |
144 | b5061ac8 | Panagiotis Kanavos | } |
145 | b5061ac8 | Panagiotis Kanavos | catch (Exception exc) |
146 | b5061ac8 | Panagiotis Kanavos | { |
147 | b5061ac8 | Panagiotis Kanavos | Trace.TraceError("[ERROR] Index Local - {0}", exc); |
148 | b5061ac8 | Panagiotis Kanavos | } |
149 | b5061ac8 | Panagiotis Kanavos | finally |
150 | b5061ac8 | Panagiotis Kanavos | { |
151 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[END] Inxed Local"); |
152 | b5061ac8 | Panagiotis Kanavos | } |
153 | b5061ac8 | Panagiotis Kanavos | } |
154 | b5061ac8 | Panagiotis Kanavos | |
155 | 0eea575a | Panagiotis Kanavos | private void RestartInterruptedFiles() |
156 | 0eea575a | Panagiotis Kanavos | { |
157 | 3c43ec9b | Panagiotis Kanavos | var interruptedStates = new[] { FileOverlayStatus.Unversioned, FileOverlayStatus.Modified }; |
158 | 0eea575a | Panagiotis Kanavos | var filesQuery = from state in FileState.Queryable |
159 | 0eea575a | Panagiotis Kanavos | where interruptedStates.Contains(state.OverlayStatus) |
160 | 0eea575a | Panagiotis Kanavos | select new WorkflowState |
161 | 0eea575a | Panagiotis Kanavos | { |
162 | 0eea575a | Panagiotis Kanavos | Path = state.FilePath.ToLower(), |
163 | 0eea575a | Panagiotis Kanavos | FileName = Path.GetFileName(state.FilePath).ToLower(), |
164 | 0eea575a | Panagiotis Kanavos | Status=state.OverlayStatus==FileOverlayStatus.Unversioned? |
165 | 0eea575a | Panagiotis Kanavos | FileStatus.Created: |
166 | 0eea575a | Panagiotis Kanavos | FileStatus.Modified, |
167 | 0eea575a | Panagiotis Kanavos | TriggeringChange = state.OverlayStatus==FileOverlayStatus.Unversioned? |
168 | 0eea575a | Panagiotis Kanavos | WatcherChangeTypes.Created: |
169 | 0eea575a | Panagiotis Kanavos | WatcherChangeTypes.Changed |
170 | 0eea575a | Panagiotis Kanavos | }; |
171 | 0eea575a | Panagiotis Kanavos | _uploadEvents.AddFromEnumerable(filesQuery,false); |
172 | 0eea575a | Panagiotis Kanavos | |
173 | 0eea575a | Panagiotis Kanavos | } |
174 | 0eea575a | Panagiotis Kanavos | |
175 | eeee29e3 | Panagiotis Kanavos | private void StartStatusService() |
176 | eeee29e3 | Panagiotis Kanavos | { |
177 | eeee29e3 | Panagiotis Kanavos | // Create a ServiceHost for the CalculatorService type and provide the base address. |
178 | 5bcf6d70 | Panagiotis Kanavos | var baseAddress = new Uri("net.pipe://localhost/pithos"); |
179 | 5bcf6d70 | Panagiotis Kanavos | _statusService = new ServiceHost(typeof(StatusService), baseAddress); |
180 | eeee29e3 | Panagiotis Kanavos | |
181 | 5bcf6d70 | Panagiotis Kanavos | var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None); |
182 | 5bcf6d70 | Panagiotis Kanavos | |
183 | 5bcf6d70 | Panagiotis Kanavos | _statusService.AddServiceEndpoint(typeof(IStatusService), binding, "net.pipe://localhost/pithos/statuscache"); |
184 | 5bcf6d70 | Panagiotis Kanavos | _statusService.AddServiceEndpoint(typeof (ISettingsService), binding, "net.pipe://localhost/pithos/settings"); |
185 | 5bcf6d70 | Panagiotis Kanavos | |
186 | 5bcf6d70 | Panagiotis Kanavos | |
187 | 5bcf6d70 | Panagiotis Kanavos | //// Add a mex endpoint |
188 | 5bcf6d70 | Panagiotis Kanavos | var smb = new ServiceMetadataBehavior |
189 | 5bcf6d70 | Panagiotis Kanavos | { |
190 | 5bcf6d70 | Panagiotis Kanavos | HttpGetEnabled = true, |
191 | 5bcf6d70 | Panagiotis Kanavos | HttpGetUrl = new Uri("http://localhost:30000/pithos/mex") |
192 | 5bcf6d70 | Panagiotis Kanavos | }; |
193 | 5bcf6d70 | Panagiotis Kanavos | _statusService.Description.Behaviors.Add(smb); |
194 | 5bcf6d70 | Panagiotis Kanavos | |
195 | 5bcf6d70 | Panagiotis Kanavos | |
196 | eeee29e3 | Panagiotis Kanavos | _statusService.Open(); |
197 | eeee29e3 | Panagiotis Kanavos | } |
198 | eeee29e3 | Panagiotis Kanavos | |
199 | eeee29e3 | Panagiotis Kanavos | private void StopStatusService() |
200 | eeee29e3 | Panagiotis Kanavos | { |
201 | eeee29e3 | Panagiotis Kanavos | if (_statusService == null) |
202 | eeee29e3 | Panagiotis Kanavos | return; |
203 | eeee29e3 | Panagiotis Kanavos | |
204 | eeee29e3 | Panagiotis Kanavos | if (_statusService.State == CommunicationState.Faulted) |
205 | eeee29e3 | Panagiotis Kanavos | _statusService.Abort(); |
206 | eeee29e3 | Panagiotis Kanavos | else if (_statusService.State != CommunicationState.Closed) |
207 | eeee29e3 | Panagiotis Kanavos | _statusService.Close(); |
208 | eeee29e3 | Panagiotis Kanavos | _statusService = null; |
209 | eeee29e3 | Panagiotis Kanavos | |
210 | eeee29e3 | Panagiotis Kanavos | } |
211 | eeee29e3 | Panagiotis Kanavos | |
212 | eeee29e3 | Panagiotis Kanavos | |
213 | 29672672 | Panagiotis Kanavos | private void StartNetwork() |
214 | 29672672 | Panagiotis Kanavos | { |
215 | 637bc368 | Panagiotis Kanavos | |
216 | 637bc368 | Panagiotis Kanavos | bool connected = NetworkListManager.IsConnectedToInternet; |
217 | 29672672 | Panagiotis Kanavos | //If we are not connected retry later |
218 | 29672672 | Panagiotis Kanavos | if (!connected) |
219 | 29672672 | Panagiotis Kanavos | { |
220 | 29672672 | Panagiotis Kanavos | Task.Factory.StartNewDelayed(10000, StartNetwork); |
221 | 29672672 | Panagiotis Kanavos | return; |
222 | 29672672 | Panagiotis Kanavos | } |
223 | 29672672 | Panagiotis Kanavos | |
224 | 29672672 | Panagiotis Kanavos | try |
225 | 29672672 | Panagiotis Kanavos | { |
226 | 3c43ec9b | Panagiotis Kanavos | CloudClient.UsePithos = this.UsePithos; |
227 | 0eea575a | Panagiotis Kanavos | CloudClient.Authenticate(UserName, ApiKey); |
228 | 29672672 | Panagiotis Kanavos | |
229 | 0eea575a | Panagiotis Kanavos | StartListening(RootPath); |
230 | 29672672 | Panagiotis Kanavos | StartSending(); |
231 | 29672672 | Panagiotis Kanavos | } |
232 | 29672672 | Panagiotis Kanavos | catch (Exception) |
233 | 29672672 | Panagiotis Kanavos | { |
234 | 29672672 | Panagiotis Kanavos | //Faild to authenticate due to network or account error |
235 | 29672672 | Panagiotis Kanavos | //Retry after a while |
236 | 29672672 | Panagiotis Kanavos | Task.Factory.StartNewDelayed(10000, StartNetwork); |
237 | 29672672 | Panagiotis Kanavos | } |
238 | d78cbf09 | Panagiotis Kanavos | } |
239 | d78cbf09 | Panagiotis Kanavos | |
240 | 3c43ec9b | Panagiotis Kanavos | public bool UsePithos { get; set; } |
241 | 3c43ec9b | Panagiotis Kanavos | |
242 | d78cbf09 | Panagiotis Kanavos | internal enum CloudActionType |
243 | d78cbf09 | Panagiotis Kanavos | { |
244 | d78cbf09 | Panagiotis Kanavos | Upload=0, |
245 | d78cbf09 | Panagiotis Kanavos | Download, |
246 | d78cbf09 | Panagiotis Kanavos | UploadUnconditional, |
247 | d78cbf09 | Panagiotis Kanavos | DownloadUnconditional, |
248 | d78cbf09 | Panagiotis Kanavos | DeleteLocal, |
249 | d78cbf09 | Panagiotis Kanavos | DeleteCloud |
250 | d78cbf09 | Panagiotis Kanavos | } |
251 | d78cbf09 | Panagiotis Kanavos | |
252 | d78cbf09 | Panagiotis Kanavos | internal class ListenerAction |
253 | d78cbf09 | Panagiotis Kanavos | { |
254 | d78cbf09 | Panagiotis Kanavos | public CloudActionType Action { get; set; } |
255 | d78cbf09 | Panagiotis Kanavos | public FileInfo LocalFile { get; set; } |
256 | d78cbf09 | Panagiotis Kanavos | public ObjectInfo CloudFile { get; set; } |
257 | d78cbf09 | Panagiotis Kanavos | |
258 | d78cbf09 | Panagiotis Kanavos | public Lazy<string> LocalHash { get; set; } |
259 | d78cbf09 | Panagiotis Kanavos | |
260 | d78cbf09 | Panagiotis Kanavos | public ListenerAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile) |
261 | d78cbf09 | Panagiotis Kanavos | { |
262 | d78cbf09 | Panagiotis Kanavos | Action = action; |
263 | d78cbf09 | Panagiotis Kanavos | LocalFile = localFile; |
264 | d78cbf09 | Panagiotis Kanavos | CloudFile = cloudFile; |
265 | b5061ac8 | Panagiotis Kanavos | LocalHash=new Lazy<string>(()=>Signature.CalculateHash(LocalFile.FullName),LazyThreadSafetyMode.ExecutionAndPublication); |
266 | d78cbf09 | Panagiotis Kanavos | } |
267 | d78cbf09 | Panagiotis Kanavos | |
268 | d78cbf09 | Panagiotis Kanavos | } |
269 | d78cbf09 | Panagiotis Kanavos | |
270 | d78cbf09 | Panagiotis Kanavos | internal class LocalFileComparer:EqualityComparer<ListenerAction> |
271 | d78cbf09 | Panagiotis Kanavos | { |
272 | d78cbf09 | Panagiotis Kanavos | public override bool Equals(ListenerAction x, ListenerAction y) |
273 | d78cbf09 | Panagiotis Kanavos | { |
274 | d78cbf09 | Panagiotis Kanavos | if (x.Action != y.Action) |
275 | d78cbf09 | Panagiotis Kanavos | return false; |
276 | d78cbf09 | Panagiotis Kanavos | if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName)) |
277 | d78cbf09 | Panagiotis Kanavos | return false; |
278 | d78cbf09 | Panagiotis Kanavos | if (x.CloudFile != null && y.CloudFile != null && !x.CloudFile.Hash.Equals(y.CloudFile.Hash)) |
279 | d78cbf09 | Panagiotis Kanavos | return false; |
280 | d78cbf09 | Panagiotis Kanavos | if (x.CloudFile == null ^ y.CloudFile == null || |
281 | d78cbf09 | Panagiotis Kanavos | x.LocalFile == null ^ y.LocalFile == null) |
282 | d78cbf09 | Panagiotis Kanavos | return false; |
283 | d78cbf09 | Panagiotis Kanavos | return true; |
284 | d78cbf09 | Panagiotis Kanavos | } |
285 | d78cbf09 | Panagiotis Kanavos | |
286 | d78cbf09 | Panagiotis Kanavos | public override int GetHashCode(ListenerAction obj) |
287 | d78cbf09 | Panagiotis Kanavos | { |
288 | d78cbf09 | Panagiotis Kanavos | var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode(); |
289 | d78cbf09 | Panagiotis Kanavos | var hash2 = (obj.CloudFile == null) ? int.MaxValue : obj.CloudFile.Hash.GetHashCode(); |
290 | d78cbf09 | Panagiotis Kanavos | var hash3 = obj.Action.GetHashCode(); |
291 | d78cbf09 | Panagiotis Kanavos | return hash1 ^ hash2 & hash3; |
292 | d78cbf09 | Panagiotis Kanavos | } |
293 | d78cbf09 | Panagiotis Kanavos | } |
294 | d78cbf09 | Panagiotis Kanavos | |
295 | 283809f3 | Panagiotis Kanavos | private BlockingCollection<ListenerAction> _networkActions=new BlockingCollection<ListenerAction>(); |
296 | d78cbf09 | Panagiotis Kanavos | |
297 | d78cbf09 | Panagiotis Kanavos | private Timer timer; |
298 | d78cbf09 | Panagiotis Kanavos | |
299 | b5061ac8 | Panagiotis Kanavos | private void StartListening(string accountPath) |
300 | d78cbf09 | Panagiotis Kanavos | { |
301 | d78cbf09 | Panagiotis Kanavos | |
302 | b5061ac8 | Panagiotis Kanavos | ProcessRemoteFiles(accountPath); |
303 | b5061ac8 | Panagiotis Kanavos | |
304 | b5061ac8 | Panagiotis Kanavos | Task.Factory.StartNew(ProcessListenerActions); |
305 | b5061ac8 | Panagiotis Kanavos | |
306 | b5061ac8 | Panagiotis Kanavos | } |
307 | b5061ac8 | Panagiotis Kanavos | |
308 | b5061ac8 | Panagiotis Kanavos | private Task ProcessRemoteFiles(string accountPath) |
309 | b5061ac8 | Panagiotis Kanavos | { |
310 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[LISTENER] Scheduled"); |
311 | b5061ac8 | Panagiotis Kanavos | return Task.Factory.StartNewDelayed(10000) |
312 | 3c43ec9b | Panagiotis Kanavos | .ContinueWith(t=>CloudClient.ListObjects(PithosContainer)) |
313 | d78cbf09 | Panagiotis Kanavos | .ContinueWith(task => |
314 | d78cbf09 | Panagiotis Kanavos | { |
315 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[LISTENER] Start Processing"); |
316 | b5061ac8 | Panagiotis Kanavos | |
317 | b5061ac8 | Panagiotis Kanavos | var remoteObjects = task.Result; |
318 | b5061ac8 | Panagiotis Kanavos | /* |
319 | b5061ac8 | Panagiotis Kanavos | if (remoteObjects.Count == 0) |
320 | d78cbf09 | Panagiotis Kanavos | return; |
321 | b5061ac8 | Panagiotis Kanavos | */ |
322 | d78cbf09 | Panagiotis Kanavos | |
323 | b5061ac8 | Panagiotis Kanavos | var pithosDir = new DirectoryInfo(accountPath); |
324 | d78cbf09 | Panagiotis Kanavos | |
325 | b5061ac8 | Panagiotis Kanavos | var remoteFiles = from info in remoteObjects |
326 | 283809f3 | Panagiotis Kanavos | select info.Name.ToLower(); |
327 | d78cbf09 | Panagiotis Kanavos | |
328 | d78cbf09 | Panagiotis Kanavos | var onlyLocal = from localFile in pithosDir.EnumerateFiles() |
329 | 283809f3 | Panagiotis Kanavos | where !remoteFiles.Contains(localFile.Name.ToLower()) |
330 | d78cbf09 | Panagiotis Kanavos | select new ListenerAction(CloudActionType.UploadUnconditional, localFile,null); |
331 | d78cbf09 | Panagiotis Kanavos | |
332 | 283809f3 | Panagiotis Kanavos | |
333 | 283809f3 | Panagiotis Kanavos | |
334 | 283809f3 | Panagiotis Kanavos | var localNames = from info in pithosDir.EnumerateFiles() |
335 | 283809f3 | Panagiotis Kanavos | select info.Name.ToLower(); |
336 | 283809f3 | Panagiotis Kanavos | |
337 | b5061ac8 | Panagiotis Kanavos | var onlyRemote = from upFile in remoteObjects |
338 | 283809f3 | Panagiotis Kanavos | where !localNames.Contains(upFile.Name.ToLower()) |
339 | d78cbf09 | Panagiotis Kanavos | select new ListenerAction(CloudActionType.DownloadUnconditional,null,upFile); |
340 | d78cbf09 | Panagiotis Kanavos | |
341 | d78cbf09 | Panagiotis Kanavos | |
342 | b5061ac8 | Panagiotis Kanavos | var commonObjects = from upFile in remoteObjects |
343 | d78cbf09 | Panagiotis Kanavos | join localFile in pithosDir.EnumerateFiles() |
344 | 283809f3 | Panagiotis Kanavos | on upFile.Name.ToLower() equals localFile.Name.ToLower() |
345 | b5061ac8 | Panagiotis Kanavos | select new ListenerAction(CloudActionType.Download, localFile, upFile); |
346 | d78cbf09 | Panagiotis Kanavos | |
347 | d78cbf09 | Panagiotis Kanavos | var uniques = |
348 | b5061ac8 | Panagiotis Kanavos | onlyLocal.Union(onlyRemote).Union(commonObjects) |
349 | 283809f3 | Panagiotis Kanavos | .Except(_networkActions,new LocalFileComparer()); |
350 | b5061ac8 | Panagiotis Kanavos | |
351 | 283809f3 | Panagiotis Kanavos | _networkActions.AddFromEnumerable(uniques, false); |
352 | d78cbf09 | Panagiotis Kanavos | |
353 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[LISTENER] End Processing"); |
354 | b5061ac8 | Panagiotis Kanavos | |
355 | b5061ac8 | Panagiotis Kanavos | } |
356 | b5061ac8 | Panagiotis Kanavos | ).ContinueWith(t=> |
357 | b5061ac8 | Panagiotis Kanavos | { |
358 | b5061ac8 | Panagiotis Kanavos | if (t.IsFaulted) |
359 | b5061ac8 | Panagiotis Kanavos | { |
360 | b5061ac8 | Panagiotis Kanavos | Trace.TraceError("[LISTENER] Exception: {0}",t.Exception); |
361 | b5061ac8 | Panagiotis Kanavos | } |
362 | b5061ac8 | Panagiotis Kanavos | else |
363 | b5061ac8 | Panagiotis Kanavos | { |
364 | b5061ac8 | Panagiotis Kanavos | Trace.TraceInformation("[LISTENER] Finished"); |
365 | b5061ac8 | Panagiotis Kanavos | } |
366 | b5061ac8 | Panagiotis Kanavos | ProcessRemoteFiles(accountPath); |
367 | b5061ac8 | Panagiotis Kanavos | }); |
368 | b5061ac8 | Panagiotis Kanavos | } |
369 | b5061ac8 | Panagiotis Kanavos | |
370 | b5061ac8 | Panagiotis Kanavos | private void ProcessListenerActions() |
371 | b5061ac8 | Panagiotis Kanavos | { |
372 | 283809f3 | Panagiotis Kanavos | foreach(var action in _networkActions.GetConsumingEnumerable()) |
373 | b5061ac8 | Panagiotis Kanavos | { |
374 | 3c43ec9b | Panagiotis Kanavos | Trace.TraceInformation("[ACTION] Start Processing {0}:{1}->{2}",action.Action,action.LocalFile,action.CloudFile.Name); |
375 | b5061ac8 | Panagiotis Kanavos | var localFile = action.LocalFile; |
376 | b5061ac8 | Panagiotis Kanavos | var cloudFile = action.CloudFile; |
377 | b5061ac8 | Panagiotis Kanavos | var downloadPath = (cloudFile == null)? String.Empty |
378 | 0eea575a | Panagiotis Kanavos | : Path.Combine(RootPath,cloudFile.Name); |
379 | b5061ac8 | Panagiotis Kanavos | try |
380 | b5061ac8 | Panagiotis Kanavos | { |
381 | b5061ac8 | Panagiotis Kanavos | switch (action.Action) |
382 | b5061ac8 | Panagiotis Kanavos | { |
383 | b5061ac8 | Panagiotis Kanavos | case CloudActionType.UploadUnconditional: |
384 | b5061ac8 | Panagiotis Kanavos | |
385 | b5061ac8 | Panagiotis Kanavos | UploadCloudFile(localFile.Name,localFile.Length,localFile.FullName,action.LocalHash.Value); |
386 | b5061ac8 | Panagiotis Kanavos | break; |
387 | b5061ac8 | Panagiotis Kanavos | case CloudActionType.DownloadUnconditional: |
388 | 3c43ec9b | Panagiotis Kanavos | DownloadCloudFile(PithosContainer,cloudFile.Name,downloadPath); |
389 | b5061ac8 | Panagiotis Kanavos | break; |
390 | b5061ac8 | Panagiotis Kanavos | case CloudActionType.Download: |
391 | b5061ac8 | Panagiotis Kanavos | if (File.Exists(downloadPath)) |
392 | b5061ac8 | Panagiotis Kanavos | { |
393 | b5061ac8 | Panagiotis Kanavos | if (cloudFile.Hash !=action.LocalHash.Value) |
394 | b5061ac8 | Panagiotis Kanavos | { |
395 | b5061ac8 | Panagiotis Kanavos | var lastLocalTime =localFile.LastWriteTime; |
396 | b5061ac8 | Panagiotis Kanavos | var lastUpTime =cloudFile.Last_Modified; |
397 | b5061ac8 | Panagiotis Kanavos | if (lastUpTime <=lastLocalTime) |
398 | b5061ac8 | Panagiotis Kanavos | { |
399 | b5061ac8 | Panagiotis Kanavos | //Files in conflict |
400 | b5061ac8 | Panagiotis Kanavos | StatusKeeper.SetFileOverlayStatus(downloadPath,FileOverlayStatus.Conflict); |
401 | b5061ac8 | Panagiotis Kanavos | } |
402 | b5061ac8 | Panagiotis Kanavos | else |
403 | 3c43ec9b | Panagiotis Kanavos | DownloadCloudFile(PithosContainer,action.CloudFile.Name,downloadPath); |
404 | b5061ac8 | Panagiotis Kanavos | } |
405 | b5061ac8 | Panagiotis Kanavos | } |
406 | b5061ac8 | Panagiotis Kanavos | else |
407 | 3c43ec9b | Panagiotis Kanavos | DownloadCloudFile(PithosContainer,action.CloudFile.Name,downloadPath); |
408 | b5061ac8 | Panagiotis Kanavos | break; |
409 | b5061ac8 | Panagiotis Kanavos | } |
410 | 3c43ec9b | Panagiotis Kanavos | Trace.TraceInformation("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name); |
411 | b5061ac8 | Panagiotis Kanavos | } |
412 | b5061ac8 | Panagiotis Kanavos | catch (Exception exc) |
413 | b5061ac8 | Panagiotis Kanavos | { |
414 | b5061ac8 | Panagiotis Kanavos | Trace.TraceError("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}", |
415 | 0eea575a | Panagiotis Kanavos | action.Action, action.LocalFile,action.CloudFile,exc); |
416 | b5061ac8 | Panagiotis Kanavos | |
417 | 283809f3 | Panagiotis Kanavos | _networkActions.Add(action); |
418 | b5061ac8 | Panagiotis Kanavos | } |
419 | b5061ac8 | Panagiotis Kanavos | } |
420 | d78cbf09 | Panagiotis Kanavos | } |
421 | d78cbf09 | Panagiotis Kanavos | |
422 | 283809f3 | Panagiotis Kanavos | |
423 | d78cbf09 | Panagiotis Kanavos | |
424 | 29672672 | Panagiotis Kanavos | private void StartMonitoringFiles(string path) |
425 | d78cbf09 | Panagiotis Kanavos | { |
426 | 29672672 | Panagiotis Kanavos | _watcher = new FileSystemWatcher(path); |
427 | 29672672 | Panagiotis Kanavos | _watcher.Changed += OnFileEvent; |
428 | 29672672 | Panagiotis Kanavos | _watcher.Created += OnFileEvent; |
429 | 29672672 | Panagiotis Kanavos | _watcher.Deleted += OnFileEvent; |
430 | 29672672 | Panagiotis Kanavos | _watcher.Renamed += OnRenameEvent; |
431 | 29672672 | Panagiotis Kanavos | _watcher.EnableRaisingEvents = true; |
432 | 29672672 | Panagiotis Kanavos | |
433 | 283809f3 | Panagiotis Kanavos | Task.Factory.StartNew(ProcesFileEvents,_cancellationSource.Token); |
434 | 283809f3 | Panagiotis Kanavos | } |
435 | 283809f3 | Panagiotis Kanavos | |
436 | 283809f3 | Panagiotis Kanavos | private void ProcesFileEvents() |
437 | 283809f3 | Panagiotis Kanavos | { |
438 | 283809f3 | Panagiotis Kanavos | foreach (var state in _fileEvents.GetConsumingEnumerable()) |
439 | 283809f3 | Panagiotis Kanavos | { |
440 | 283809f3 | Panagiotis Kanavos | try |
441 | 283809f3 | Panagiotis Kanavos | { |
442 | 283809f3 | Panagiotis Kanavos | var networkState=StatusKeeper.GetNetworkState(state.Path); |
443 | 283809f3 | Panagiotis Kanavos | //Skip if the file is already being downloaded or uploaded and |
444 | 283809f3 | Panagiotis Kanavos | //the change is create or modify |
445 | 283809f3 | Panagiotis Kanavos | if (networkState != NetworkState.None && |
446 | 283809f3 | Panagiotis Kanavos | ( |
447 | 283809f3 | Panagiotis Kanavos | state.TriggeringChange==WatcherChangeTypes.Created || |
448 | 283809f3 | Panagiotis Kanavos | state.TriggeringChange==WatcherChangeTypes.Changed |
449 | 283809f3 | Panagiotis Kanavos | )) |
450 | 283809f3 | Panagiotis Kanavos | continue; |
451 | 283809f3 | Panagiotis Kanavos | UpdateFileStatus(state); |
452 | 283809f3 | Panagiotis Kanavos | UpdateOverlayStatus(state); |
453 | 283809f3 | Panagiotis Kanavos | UpdateFileChecksum(state); |
454 | 283809f3 | Panagiotis Kanavos | _uploadEvents.Add(state); |
455 | 283809f3 | Panagiotis Kanavos | } |
456 | 283809f3 | Panagiotis Kanavos | catch (OperationCanceledException exc) |
457 | 283809f3 | Panagiotis Kanavos | { |
458 | 283809f3 | Panagiotis Kanavos | Trace.TraceError("[ERROR] File Event Processing:\r{0}", exc); |
459 | 283809f3 | Panagiotis Kanavos | throw; |
460 | 283809f3 | Panagiotis Kanavos | } |
461 | 283809f3 | Panagiotis Kanavos | catch (Exception exc) |
462 | 283809f3 | Panagiotis Kanavos | { |
463 | 283809f3 | Panagiotis Kanavos | Trace.TraceError("[ERROR] File Event Processing:\r{0}",exc); |
464 | 283809f3 | Panagiotis Kanavos | } |
465 | 283809f3 | Panagiotis Kanavos | } |
466 | 29672672 | Panagiotis Kanavos | } |
467 | 29672672 | Panagiotis Kanavos | |
468 | 29672672 | Panagiotis Kanavos | private void StartSending() |
469 | 29672672 | Panagiotis Kanavos | { |
470 | 29672672 | Panagiotis Kanavos | Task.Factory.StartNew(() => |
471 | 29672672 | Panagiotis Kanavos | { |
472 | 29672672 | Panagiotis Kanavos | foreach (var state in _uploadEvents.GetConsumingEnumerable()) |
473 | 29672672 | Panagiotis Kanavos | { |
474 | 29672672 | Panagiotis Kanavos | try |
475 | 29672672 | Panagiotis Kanavos | { |
476 | d78cbf09 | Panagiotis Kanavos | SynchToCloud(state); |
477 | d78cbf09 | Panagiotis Kanavos | } |
478 | d78cbf09 | Panagiotis Kanavos | catch (OperationCanceledException) |
479 | d78cbf09 | Panagiotis Kanavos | { |
480 | d78cbf09 | Panagiotis Kanavos | throw; |
481 | d78cbf09 | Panagiotis Kanavos | } |
482 | d78cbf09 | Panagiotis Kanavos | catch(Exception ex) |
483 | 0eea575a | Panagiotis Kanavos | { |
484 | 0eea575a | Panagiotis Kanavos | Trace.TraceError("[ERROR] Synch for {0}:\r{1}",state.FileName,ex); |
485 | 0eea575a | Panagiotis Kanavos | } |
486 | d78cbf09 | Panagiotis Kanavos | } |
487 | d78cbf09 | Panagiotis Kanavos | |
488 | d78cbf09 | Panagiotis Kanavos | },_cancellationSource.Token); |
489 | d78cbf09 | Panagiotis Kanavos | } |
490 | d78cbf09 | Panagiotis Kanavos | |
491 | d78cbf09 | Panagiotis Kanavos | |
492 | d78cbf09 | Panagiotis Kanavos | private WorkflowState SynchToCloud(WorkflowState state) |
493 | d78cbf09 | Panagiotis Kanavos | { |
494 | d78cbf09 | Panagiotis Kanavos | if (state.Skip) |
495 | d78cbf09 | Panagiotis Kanavos | return state; |
496 | d78cbf09 | Panagiotis Kanavos | string path = state.Path; |
497 | d78cbf09 | Panagiotis Kanavos | string fileName = Path.GetFileName(path); |
498 | d78cbf09 | Panagiotis Kanavos | |
499 | d78cbf09 | Panagiotis Kanavos | switch(state.Status) |
500 | d78cbf09 | Panagiotis Kanavos | { |
501 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Created: |
502 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Modified: |
503 | d78cbf09 | Panagiotis Kanavos | var info = new FileInfo(path); |
504 | d78cbf09 | Panagiotis Kanavos | long fileSize = info.Length; |
505 | d78cbf09 | Panagiotis Kanavos | UploadCloudFile(fileName, fileSize, path,state.Hash); |
506 | d78cbf09 | Panagiotis Kanavos | break; |
507 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Deleted: |
508 | d78cbf09 | Panagiotis Kanavos | DeleteCloudFile(fileName); |
509 | d78cbf09 | Panagiotis Kanavos | break; |
510 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Renamed: |
511 | d78cbf09 | Panagiotis Kanavos | RenameCloudFile(state); |
512 | d78cbf09 | Panagiotis Kanavos | break; |
513 | d78cbf09 | Panagiotis Kanavos | } |
514 | d78cbf09 | Panagiotis Kanavos | return state; |
515 | d78cbf09 | Panagiotis Kanavos | } |
516 | d78cbf09 | Panagiotis Kanavos | |
517 | d78cbf09 | Panagiotis Kanavos | private void RenameCloudFile(WorkflowState state) |
518 | d78cbf09 | Panagiotis Kanavos | { |
519 | 3c43ec9b | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified); |
520 | d78cbf09 | Panagiotis Kanavos | |
521 | d78cbf09 | Panagiotis Kanavos | |
522 | d78cbf09 | Panagiotis Kanavos | |
523 | 3c43ec9b | Panagiotis Kanavos | CloudClient.MoveObject(PithosContainer, state.OldFileName,PithosContainer, state.FileName); |
524 | d78cbf09 | Panagiotis Kanavos | |
525 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.SetFileStatus(state.Path, FileStatus.Unchanged); |
526 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal); |
527 | d78cbf09 | Panagiotis Kanavos | Workflow.RaiseChangeNotification(state.Path); |
528 | d78cbf09 | Panagiotis Kanavos | } |
529 | d78cbf09 | Panagiotis Kanavos | |
530 | d78cbf09 | Panagiotis Kanavos | private void DeleteCloudFile(string fileName) |
531 | d78cbf09 | Panagiotis Kanavos | { |
532 | d78cbf09 | Panagiotis Kanavos | Contract.Requires(!Path.IsPathRooted(fileName)); |
533 | d78cbf09 | Panagiotis Kanavos | |
534 | 3c43ec9b | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(fileName, FileOverlayStatus.Modified); |
535 | 3c43ec9b | Panagiotis Kanavos | |
536 | 3c43ec9b | Panagiotis Kanavos | CloudClient.MoveObject(PithosContainer,fileName,TrashContainer,fileName); |
537 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.ClearFileStatus(fileName); |
538 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.RemoveFileOverlayStatus(fileName); |
539 | d78cbf09 | Panagiotis Kanavos | } |
540 | d78cbf09 | Panagiotis Kanavos | |
541 | 283809f3 | Panagiotis Kanavos | private void DownloadCloudFile(string container, string fileName, string localPath) |
542 | 283809f3 | Panagiotis Kanavos | { |
543 | 283809f3 | Panagiotis Kanavos | StatusKeeper.SetNetworkState(localPath,NetworkState.Downloading); |
544 | 283809f3 | Panagiotis Kanavos | CloudClient.GetObject(container, fileName, localPath) |
545 | 283809f3 | Panagiotis Kanavos | .ContinueWith(t=> |
546 | 283809f3 | Panagiotis Kanavos | CloudClient.GetObjectInfo(container,fileName)) |
547 | 283809f3 | Panagiotis Kanavos | .ContinueWith(t=> |
548 | 283809f3 | Panagiotis Kanavos | StatusKeeper.StoreInfo(fileName,t.Result)) |
549 | 283809f3 | Panagiotis Kanavos | .ContinueWith(t=> |
550 | 283809f3 | Panagiotis Kanavos | StatusKeeper.SetNetworkState(localPath,NetworkState.None)) |
551 | 283809f3 | Panagiotis Kanavos | .Wait(); |
552 | 283809f3 | Panagiotis Kanavos | } |
553 | 283809f3 | Panagiotis Kanavos | |
554 | d78cbf09 | Panagiotis Kanavos | private void UploadCloudFile(string fileName, long fileSize, string path,string hash) |
555 | d78cbf09 | Panagiotis Kanavos | { |
556 | d78cbf09 | Panagiotis Kanavos | Contract.Requires(!Path.IsPathRooted(fileName)); |
557 | 283809f3 | Panagiotis Kanavos | |
558 | 283809f3 | Panagiotis Kanavos | StatusKeeper.SetNetworkState(fileName,NetworkState.Uploading); |
559 | 283809f3 | Panagiotis Kanavos | |
560 | 283809f3 | Panagiotis Kanavos | //Even if GetObjectInfo times out, we can proceed with the upload |
561 | 3c43ec9b | Panagiotis Kanavos | var info = CloudClient.GetObjectInfo(PithosContainer, fileName); |
562 | 0eea575a | Panagiotis Kanavos | Task.Factory.StartNew(() => |
563 | d78cbf09 | Panagiotis Kanavos | { |
564 | 0eea575a | Panagiotis Kanavos | if (hash != info.Hash) |
565 | 0eea575a | Panagiotis Kanavos | { |
566 | 0eea575a | Panagiotis Kanavos | Task.Factory.StartNew(() => |
567 | 3c43ec9b | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(path, FileOverlayStatus.Modified)) |
568 | 0eea575a | Panagiotis Kanavos | .ContinueWith(t => |
569 | 3c43ec9b | Panagiotis Kanavos | CloudClient.PutObject(PithosContainer, fileName, path, hash)); |
570 | 0eea575a | Panagiotis Kanavos | } |
571 | 283809f3 | Panagiotis Kanavos | else |
572 | 283809f3 | Panagiotis Kanavos | { |
573 | 283809f3 | Panagiotis Kanavos | this.StatusKeeper.StoreInfo(path,info); |
574 | 283809f3 | Panagiotis Kanavos | } |
575 | d78cbf09 | Panagiotis Kanavos | } |
576 | 0eea575a | Panagiotis Kanavos | ) |
577 | 283809f3 | Panagiotis Kanavos | .ContinueWith(t => |
578 | 283809f3 | Panagiotis Kanavos | this.StatusKeeper.SetFileState(path, FileStatus.Unchanged, FileOverlayStatus.Normal)) |
579 | 283809f3 | Panagiotis Kanavos | .ContinueWith(t=> |
580 | 283809f3 | Panagiotis Kanavos | this.StatusKeeper.SetNetworkState(path,NetworkState.None)) |
581 | 0eea575a | Panagiotis Kanavos | .Wait(); |
582 | d78cbf09 | Panagiotis Kanavos | Workflow.RaiseChangeNotification(path); |
583 | d78cbf09 | Panagiotis Kanavos | } |
584 | d78cbf09 | Panagiotis Kanavos | |
585 | d78cbf09 | Panagiotis Kanavos | private Dictionary<WatcherChangeTypes, FileStatus> _statusDict = new Dictionary<WatcherChangeTypes, FileStatus> |
586 | d78cbf09 | Panagiotis Kanavos | { |
587 | d78cbf09 | Panagiotis Kanavos | {WatcherChangeTypes.Created,FileStatus.Created}, |
588 | d78cbf09 | Panagiotis Kanavos | {WatcherChangeTypes.Changed,FileStatus.Modified}, |
589 | d78cbf09 | Panagiotis Kanavos | {WatcherChangeTypes.Deleted,FileStatus.Deleted}, |
590 | d78cbf09 | Panagiotis Kanavos | {WatcherChangeTypes.Renamed,FileStatus.Renamed} |
591 | d78cbf09 | Panagiotis Kanavos | }; |
592 | d78cbf09 | Panagiotis Kanavos | |
593 | d78cbf09 | Panagiotis Kanavos | private WorkflowState UpdateFileStatus(WorkflowState state) |
594 | d78cbf09 | Panagiotis Kanavos | { |
595 | d78cbf09 | Panagiotis Kanavos | string path = state.Path; |
596 | d78cbf09 | Panagiotis Kanavos | FileStatus status = _statusDict[state.TriggeringChange]; |
597 | d78cbf09 | Panagiotis Kanavos | var oldStatus = Workflow.StatusKeeper.GetFileStatus(path); |
598 | d78cbf09 | Panagiotis Kanavos | if (status == oldStatus) |
599 | d78cbf09 | Panagiotis Kanavos | { |
600 | d78cbf09 | Panagiotis Kanavos | state.Status = status; |
601 | d78cbf09 | Panagiotis Kanavos | state.Skip = true; |
602 | d78cbf09 | Panagiotis Kanavos | return state; |
603 | d78cbf09 | Panagiotis Kanavos | } |
604 | d78cbf09 | Panagiotis Kanavos | if (state.Status == FileStatus.Renamed) |
605 | d78cbf09 | Panagiotis Kanavos | Workflow.ClearFileStatus(path); |
606 | d78cbf09 | Panagiotis Kanavos | |
607 | d78cbf09 | Panagiotis Kanavos | state.Status = Workflow.SetFileStatus(path, status); |
608 | d78cbf09 | Panagiotis Kanavos | return state; |
609 | d78cbf09 | Panagiotis Kanavos | } |
610 | d78cbf09 | Panagiotis Kanavos | |
611 | d78cbf09 | Panagiotis Kanavos | private WorkflowState UpdateOverlayStatus(WorkflowState state) |
612 | d78cbf09 | Panagiotis Kanavos | { |
613 | d78cbf09 | Panagiotis Kanavos | if (state.Skip) |
614 | d78cbf09 | Panagiotis Kanavos | return state; |
615 | d78cbf09 | Panagiotis Kanavos | |
616 | d78cbf09 | Panagiotis Kanavos | switch (state.Status) |
617 | d78cbf09 | Panagiotis Kanavos | { |
618 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Created: |
619 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Modified: |
620 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified); |
621 | d78cbf09 | Panagiotis Kanavos | break; |
622 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Deleted: |
623 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.RemoveFileOverlayStatus(state.Path); |
624 | d78cbf09 | Panagiotis Kanavos | break; |
625 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Renamed: |
626 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.RemoveFileOverlayStatus(state.OldPath); |
627 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified); |
628 | d78cbf09 | Panagiotis Kanavos | break; |
629 | d78cbf09 | Panagiotis Kanavos | case FileStatus.Unchanged: |
630 | d78cbf09 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal); |
631 | d78cbf09 | Panagiotis Kanavos | break; |
632 | d78cbf09 | Panagiotis Kanavos | } |
633 | d78cbf09 | Panagiotis Kanavos | |
634 | d78cbf09 | Panagiotis Kanavos | if (state.Status==FileStatus.Deleted) |
635 | d78cbf09 | Panagiotis Kanavos | Workflow.RaiseChangeNotification(Path.GetDirectoryName(state.Path)); |
636 | d78cbf09 | Panagiotis Kanavos | else |
637 | d78cbf09 | Panagiotis Kanavos | Workflow.RaiseChangeNotification(state.Path); |
638 | d78cbf09 | Panagiotis Kanavos | return state; |
639 | d78cbf09 | Panagiotis Kanavos | } |
640 | d78cbf09 | Panagiotis Kanavos | |
641 | d78cbf09 | Panagiotis Kanavos | |
642 | d78cbf09 | Panagiotis Kanavos | private WorkflowState UpdateFileChecksum(WorkflowState state) |
643 | d78cbf09 | Panagiotis Kanavos | { |
644 | d78cbf09 | Panagiotis Kanavos | if (state.Skip) |
645 | d78cbf09 | Panagiotis Kanavos | return state; |
646 | d78cbf09 | Panagiotis Kanavos | |
647 | d78cbf09 | Panagiotis Kanavos | if (state.Status == FileStatus.Deleted) |
648 | d78cbf09 | Panagiotis Kanavos | return state; |
649 | d78cbf09 | Panagiotis Kanavos | |
650 | d78cbf09 | Panagiotis Kanavos | string path = state.Path; |
651 | b5061ac8 | Panagiotis Kanavos | string hash = Signature.CalculateHash(path); |
652 | d78cbf09 | Panagiotis Kanavos | |
653 | d78cbf09 | Panagiotis Kanavos | StatusKeeper.UpdateFileChecksum(path, hash); |
654 | d78cbf09 | Panagiotis Kanavos | |
655 | d78cbf09 | Panagiotis Kanavos | state.Hash = hash; |
656 | d78cbf09 | Panagiotis Kanavos | return state; |
657 | d78cbf09 | Panagiotis Kanavos | } |
658 | d78cbf09 | Panagiotis Kanavos | |
659 | b5061ac8 | Panagiotis Kanavos | |
660 | d78cbf09 | Panagiotis Kanavos | |
661 | d78cbf09 | Panagiotis Kanavos | private FileSystemEventArgs CalculateSignature(FileSystemEventArgs arg) |
662 | d78cbf09 | Panagiotis Kanavos | { |
663 | d78cbf09 | Panagiotis Kanavos | Debug.WriteLine(String.Format("{0} {1} {2}", arg.ChangeType, arg.Name, arg.FullPath), "INFO"); |
664 | d78cbf09 | Panagiotis Kanavos | return arg; |
665 | d78cbf09 | Panagiotis Kanavos | } |
666 | d78cbf09 | Panagiotis Kanavos | |
667 | d78cbf09 | Panagiotis Kanavos | void OnFileEvent(object sender, FileSystemEventArgs e) |
668 | d78cbf09 | Panagiotis Kanavos | { |
669 | d78cbf09 | Panagiotis Kanavos | _fileEvents.Add(new WorkflowState{Path=e.FullPath,FileName = e.Name,TriggeringChange=e.ChangeType}); |
670 | d78cbf09 | Panagiotis Kanavos | } |
671 | d78cbf09 | Panagiotis Kanavos | |
672 | d78cbf09 | Panagiotis Kanavos | void OnRenameEvent(object sender, RenamedEventArgs e) |
673 | d78cbf09 | Panagiotis Kanavos | { |
674 | d78cbf09 | Panagiotis Kanavos | _fileEvents.Add(new WorkflowState { OldPath=e.OldFullPath,OldFileName=e.OldName, |
675 | d78cbf09 | Panagiotis Kanavos | Path = e.FullPath, FileName = e.Name, TriggeringChange = e.ChangeType }); |
676 | d78cbf09 | Panagiotis Kanavos | } |
677 | d78cbf09 | Panagiotis Kanavos | |
678 | d78cbf09 | Panagiotis Kanavos | public void Stop() |
679 | d78cbf09 | Panagiotis Kanavos | { |
680 | d78cbf09 | Panagiotis Kanavos | if (_watcher != null) |
681 | d78cbf09 | Panagiotis Kanavos | { |
682 | d78cbf09 | Panagiotis Kanavos | _watcher.Changed -= OnFileEvent; |
683 | d78cbf09 | Panagiotis Kanavos | _watcher.Created -= OnFileEvent; |
684 | d78cbf09 | Panagiotis Kanavos | _watcher.Deleted -= OnFileEvent; |
685 | d78cbf09 | Panagiotis Kanavos | _watcher.Renamed -= OnRenameEvent; |
686 | d78cbf09 | Panagiotis Kanavos | _watcher.Dispose(); |
687 | d78cbf09 | Panagiotis Kanavos | } |
688 | d78cbf09 | Panagiotis Kanavos | _watcher = null; |
689 | d78cbf09 | Panagiotis Kanavos | _fileEvents.CompleteAdding(); |
690 | d78cbf09 | Panagiotis Kanavos | if (timer != null) |
691 | d78cbf09 | Panagiotis Kanavos | timer.Dispose(); |
692 | d78cbf09 | Panagiotis Kanavos | timer = null; |
693 | eeee29e3 | Panagiotis Kanavos | StopStatusService(); |
694 | d78cbf09 | Panagiotis Kanavos | } |
695 | d78cbf09 | Panagiotis Kanavos | |
696 | eeee29e3 | Panagiotis Kanavos | |
697 | d78cbf09 | Panagiotis Kanavos | ~PithosMonitor() |
698 | d78cbf09 | Panagiotis Kanavos | { |
699 | d78cbf09 | Panagiotis Kanavos | Dispose(false); |
700 | d78cbf09 | Panagiotis Kanavos | } |
701 | d78cbf09 | Panagiotis Kanavos | |
702 | d78cbf09 | Panagiotis Kanavos | public void Dispose() |
703 | d78cbf09 | Panagiotis Kanavos | { |
704 | d78cbf09 | Panagiotis Kanavos | Dispose(true); |
705 | d78cbf09 | Panagiotis Kanavos | GC.SuppressFinalize(this); |
706 | d78cbf09 | Panagiotis Kanavos | } |
707 | d78cbf09 | Panagiotis Kanavos | |
708 | d78cbf09 | Panagiotis Kanavos | protected virtual void Dispose(bool disposing) |
709 | d78cbf09 | Panagiotis Kanavos | { |
710 | d78cbf09 | Panagiotis Kanavos | if (disposing) |
711 | d78cbf09 | Panagiotis Kanavos | { |
712 | d78cbf09 | Panagiotis Kanavos | Stop(); |
713 | d78cbf09 | Panagiotis Kanavos | } |
714 | d78cbf09 | Panagiotis Kanavos | } |
715 | d78cbf09 | Panagiotis Kanavos | |
716 | d78cbf09 | Panagiotis Kanavos | |
717 | d78cbf09 | Panagiotis Kanavos | } |
718 | d78cbf09 | Panagiotis Kanavos | } |