root / trunk / Pithos.Core / Agents / WorkflowAgent.cs @ 133f83c2
History | View | Annotate | Download (9.4 kB)
1 | f3d080df | Panagiotis Kanavos | // ----------------------------------------------------------------------- |
---|---|---|---|
2 | f3d080df | Panagiotis Kanavos | // <copyright file="WorkflowAgent.cs" company="GRNET"> |
3 | f3d080df | Panagiotis Kanavos | // Copyright 2011 GRNET S.A. All rights reserved. |
4 | f3d080df | Panagiotis Kanavos | // |
5 | f3d080df | Panagiotis Kanavos | // Redistribution and use in source and binary forms, with or |
6 | f3d080df | Panagiotis Kanavos | // without modification, are permitted provided that the following |
7 | f3d080df | Panagiotis Kanavos | // conditions are met: |
8 | f3d080df | Panagiotis Kanavos | // |
9 | f3d080df | Panagiotis Kanavos | // 1. Redistributions of source code must retain the above |
10 | f3d080df | Panagiotis Kanavos | // copyright notice, this list of conditions and the following |
11 | f3d080df | Panagiotis Kanavos | // disclaimer. |
12 | f3d080df | Panagiotis Kanavos | // |
13 | f3d080df | Panagiotis Kanavos | // 2. Redistributions in binary form must reproduce the above |
14 | f3d080df | Panagiotis Kanavos | // copyright notice, this list of conditions and the following |
15 | f3d080df | Panagiotis Kanavos | // disclaimer in the documentation and/or other materials |
16 | f3d080df | Panagiotis Kanavos | // provided with the distribution. |
17 | f3d080df | Panagiotis Kanavos | // |
18 | f3d080df | Panagiotis Kanavos | // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
19 | f3d080df | Panagiotis Kanavos | // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | f3d080df | Panagiotis Kanavos | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
21 | f3d080df | Panagiotis Kanavos | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
22 | f3d080df | Panagiotis Kanavos | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | f3d080df | Panagiotis Kanavos | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | f3d080df | Panagiotis Kanavos | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
25 | f3d080df | Panagiotis Kanavos | // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
26 | f3d080df | Panagiotis Kanavos | // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 | f3d080df | Panagiotis Kanavos | // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
28 | f3d080df | Panagiotis Kanavos | // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | f3d080df | Panagiotis Kanavos | // POSSIBILITY OF SUCH DAMAGE. |
30 | f3d080df | Panagiotis Kanavos | // |
31 | f3d080df | Panagiotis Kanavos | // The views and conclusions contained in the software and |
32 | f3d080df | Panagiotis Kanavos | // documentation are those of the authors and should not be |
33 | f3d080df | Panagiotis Kanavos | // interpreted as representing official policies, either expressed |
34 | f3d080df | Panagiotis Kanavos | // or implied, of GRNET S.A. |
35 | f3d080df | Panagiotis Kanavos | // </copyright> |
36 | f3d080df | Panagiotis Kanavos | // ----------------------------------------------------------------------- |
37 | f3d080df | Panagiotis Kanavos | |
38 | f3d080df | Panagiotis Kanavos | using System; |
39 | 9c4346c9 | Panagiotis Kanavos | using System.Collections.Generic; |
40 | 9c4346c9 | Panagiotis Kanavos | using System.ComponentModel.Composition; |
41 | 9c4346c9 | Panagiotis Kanavos | using System.Diagnostics; |
42 | 9c4346c9 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
43 | 9c4346c9 | Panagiotis Kanavos | using System.IO; |
44 | 9c4346c9 | Panagiotis Kanavos | using System.Linq; |
45 | 9c4346c9 | Panagiotis Kanavos | using System.Text; |
46 | a64c87c8 | Panagiotis Kanavos | using System.Threading.Tasks; |
47 | e81dd1f6 | Panagiotis Kanavos | using Castle.ActiveRecord; |
48 | 9c4346c9 | Panagiotis Kanavos | using Pithos.Interfaces; |
49 | c53aa229 | Panagiotis Kanavos | using Pithos.Network; |
50 | 5120f3cb | Panagiotis Kanavos | using log4net; |
51 | 9c4346c9 | Panagiotis Kanavos | |
52 | 9c4346c9 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
53 | 9c4346c9 | Panagiotis Kanavos | { |
54 | 9c4346c9 | Panagiotis Kanavos | [Export] |
55 | 9c4346c9 | Panagiotis Kanavos | public class WorkflowAgent |
56 | 9c4346c9 | Panagiotis Kanavos | { |
57 | 4ec636f6 | Panagiotis Kanavos | Agent<WorkflowState> _agent; |
58 | 9c4346c9 | Panagiotis Kanavos | |
59 | 9c4346c9 | Panagiotis Kanavos | public IStatusNotification StatusNotification { get; set; } |
60 | e81dd1f6 | Panagiotis Kanavos | [System.ComponentModel.Composition.Import] |
61 | 9c4346c9 | Panagiotis Kanavos | public IStatusKeeper StatusKeeper { get; set; } |
62 | 5ce54458 | Panagiotis Kanavos | |
63 | e81dd1f6 | Panagiotis Kanavos | [System.ComponentModel.Composition.Import] |
64 | 9c4346c9 | Panagiotis Kanavos | public NetworkAgent NetworkAgent { get; set; } |
65 | 9c4346c9 | Panagiotis Kanavos | |
66 | 5120f3cb | Panagiotis Kanavos | private static readonly ILog Log = LogManager.GetLogger("WorkflowAgent"); |
67 | 5120f3cb | Panagiotis Kanavos | |
68 | 9c4346c9 | Panagiotis Kanavos | public void Start() |
69 | 9c4346c9 | Panagiotis Kanavos | { |
70 | 4ec636f6 | Panagiotis Kanavos | _agent = Agent<WorkflowState>.Start(inbox => |
71 | 9c4346c9 | Panagiotis Kanavos | { |
72 | 9c4346c9 | Panagiotis Kanavos | Action loop = null; |
73 | 9c4346c9 | Panagiotis Kanavos | loop = () => |
74 | 9c4346c9 | Panagiotis Kanavos | { |
75 | 4ec636f6 | Panagiotis Kanavos | var message = inbox.Receive(); |
76 | a64c87c8 | Panagiotis Kanavos | var process = message.Then(Process, inbox.CancellationToken); |
77 | a64c87c8 | Panagiotis Kanavos | inbox.LoopAsync(process,loop,ex=> |
78 | 5120f3cb | Panagiotis Kanavos | Log.ErrorFormat("[ERROR] Synch for {0}:\r{1}", message.Result.FileName, ex)); |
79 | 9c4346c9 | Panagiotis Kanavos | }; |
80 | 9c4346c9 | Panagiotis Kanavos | loop(); |
81 | 4ec636f6 | Panagiotis Kanavos | }); |
82 | 9c4346c9 | Panagiotis Kanavos | } |
83 | 9c4346c9 | Panagiotis Kanavos | |
84 | 4ec636f6 | Panagiotis Kanavos | private Task<object> Process(WorkflowState state) |
85 | a64c87c8 | Panagiotis Kanavos | { |
86 | c53aa229 | Panagiotis Kanavos | var accountInfo = state.AccountInfo; |
87 | 5120f3cb | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["Workflow"].Push("Process")) |
88 | a64c87c8 | Panagiotis Kanavos | { |
89 | a0dcfcc9 | Panagiotis Kanavos | try |
90 | 5120f3cb | Panagiotis Kanavos | { |
91 | 5120f3cb | Panagiotis Kanavos | |
92 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
93 | a0dcfcc9 | Panagiotis Kanavos | Log.DebugFormat("State {0} {1} {2}", state.FileName, state.Status, state.TriggeringChange); |
94 | a0dcfcc9 | Panagiotis Kanavos | |
95 | a0dcfcc9 | Panagiotis Kanavos | if (state.Skip) |
96 | a0dcfcc9 | Panagiotis Kanavos | { |
97 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}", state.FileName); |
98 | a0dcfcc9 | Panagiotis Kanavos | |
99 | a0dcfcc9 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
100 | 3c76f045 | Panagiotis Kanavos | } |
101 | 4f6d51d4 | Panagiotis Kanavos | |
102 | 3c76f045 | Panagiotis Kanavos | var info = Directory.Exists(state.Path) ? (FileSystemInfo)new DirectoryInfo(state.Path) : new FileInfo(state.Path); |
103 | 4f6d51d4 | Panagiotis Kanavos | |
104 | a0dcfcc9 | Panagiotis Kanavos | //Bypass deleted files, unless the status is Deleted |
105 | 4f6d51d4 | Panagiotis Kanavos | if (!info.Exists && state.Status != FileStatus.Deleted) |
106 | a0dcfcc9 | Panagiotis Kanavos | { |
107 | a0dcfcc9 | Panagiotis Kanavos | state.Skip = true; |
108 | 3c76f045 | Panagiotis Kanavos | this.StatusKeeper.ClearFileStatus(state.Path); |
109 | a0dcfcc9 | Panagiotis Kanavos | |
110 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName); |
111 | a0dcfcc9 | Panagiotis Kanavos | |
112 | a0dcfcc9 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
113 | a0dcfcc9 | Panagiotis Kanavos | } |
114 | a0dcfcc9 | Panagiotis Kanavos | |
115 | e81dd1f6 | Panagiotis Kanavos | using (new SessionScope(FlushAction.Never)) |
116 | a0dcfcc9 | Panagiotis Kanavos | { |
117 | e81dd1f6 | Panagiotis Kanavos | |
118 | 3c76f045 | Panagiotis Kanavos | var fileState = StatusKeeper.GetStateByFilePath(state.Path); |
119 | e81dd1f6 | Panagiotis Kanavos | |
120 | e81dd1f6 | Panagiotis Kanavos | switch (state.Status) |
121 | e81dd1f6 | Panagiotis Kanavos | { |
122 | e81dd1f6 | Panagiotis Kanavos | case FileStatus.Created: |
123 | e81dd1f6 | Panagiotis Kanavos | case FileStatus.Modified: |
124 | e81dd1f6 | Panagiotis Kanavos | NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState, |
125 | e81dd1f6 | Panagiotis Kanavos | accountInfo.BlockSize, |
126 | e81dd1f6 | Panagiotis Kanavos | accountInfo.BlockHash)); |
127 | e81dd1f6 | Panagiotis Kanavos | break; |
128 | e81dd1f6 | Panagiotis Kanavos | case FileStatus.Deleted: |
129 | 3c76f045 | Panagiotis Kanavos | if (fileState != null) |
130 | 3c76f045 | Panagiotis Kanavos | { |
131 | 3c76f045 | Panagiotis Kanavos | var children = StatusKeeper.GetChildren(fileState); |
132 | 3c76f045 | Panagiotis Kanavos | foreach (var child in children) |
133 | 3c76f045 | Panagiotis Kanavos | { |
134 | 3c76f045 | Panagiotis Kanavos | var childInfo = child.IsFolder |
135 | 3c76f045 | Panagiotis Kanavos | ? (FileSystemInfo) new DirectoryInfo(child.FilePath) |
136 | 3c76f045 | Panagiotis Kanavos | : new FileInfo(child.FilePath); |
137 | 3c76f045 | Panagiotis Kanavos | NetworkAgent.Post(new CloudDeleteAction(accountInfo, childInfo, child)); |
138 | 3c76f045 | Panagiotis Kanavos | } |
139 | 3c76f045 | Panagiotis Kanavos | } |
140 | e81dd1f6 | Panagiotis Kanavos | NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState)); |
141 | e81dd1f6 | Panagiotis Kanavos | break; |
142 | e81dd1f6 | Panagiotis Kanavos | case FileStatus.Renamed: |
143 | e81dd1f6 | Panagiotis Kanavos | FileSystemInfo oldInfo = Directory.Exists(state.OldPath) |
144 | e81dd1f6 | Panagiotis Kanavos | ? (FileSystemInfo) new DirectoryInfo(state.OldPath) |
145 | e81dd1f6 | Panagiotis Kanavos | : new FileInfo(state.OldPath); |
146 | e81dd1f6 | Panagiotis Kanavos | FileSystemInfo newInfo = Directory.Exists(state.Path) |
147 | e81dd1f6 | Panagiotis Kanavos | ? (FileSystemInfo) new DirectoryInfo(state.Path) |
148 | e81dd1f6 | Panagiotis Kanavos | : new FileInfo(state.Path); |
149 | e81dd1f6 | Panagiotis Kanavos | NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud, |
150 | e81dd1f6 | Panagiotis Kanavos | oldInfo, |
151 | e81dd1f6 | Panagiotis Kanavos | newInfo)); |
152 | e81dd1f6 | Panagiotis Kanavos | break; |
153 | e81dd1f6 | Panagiotis Kanavos | } |
154 | a0dcfcc9 | Panagiotis Kanavos | } |
155 | 5120f3cb | Panagiotis Kanavos | |
156 | 4ec636f6 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
157 | 5120f3cb | Panagiotis Kanavos | } |
158 | a0dcfcc9 | Panagiotis Kanavos | catch (Exception ex) |
159 | 5120f3cb | Panagiotis Kanavos | { |
160 | a0dcfcc9 | Panagiotis Kanavos | Log.Error(ex.ToString()); |
161 | a0dcfcc9 | Panagiotis Kanavos | throw; |
162 | 5120f3cb | Panagiotis Kanavos | } |
163 | 5120f3cb | Panagiotis Kanavos | } |
164 | a64c87c8 | Panagiotis Kanavos | } |
165 | a64c87c8 | Panagiotis Kanavos | |
166 | a64c87c8 | Panagiotis Kanavos | |
167 | c53aa229 | Panagiotis Kanavos | //Starts interrupted files for a specific account |
168 | c53aa229 | Panagiotis Kanavos | public void RestartInterruptedFiles(AccountInfo accountInfo) |
169 | 9c4346c9 | Panagiotis Kanavos | { |
170 | 5ce54458 | Panagiotis Kanavos | |
171 | 5120f3cb | Panagiotis Kanavos | StatusNotification.NotifyChange("Restart processing interrupted files", TraceLevel.Verbose); |
172 | 9c4346c9 | Panagiotis Kanavos | |
173 | 5120f3cb | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["Workflow"].Push("Restart")) |
174 | 5120f3cb | Panagiotis Kanavos | { |
175 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
176 | 5120f3cb | Panagiotis Kanavos | Log.Debug("Starting interrupted files"); |
177 | c53aa229 | Panagiotis Kanavos | |
178 | 77e10b4f | Panagiotis Kanavos | var cachePath = Path.Combine(accountInfo.AccountPath, FolderConstants.CacheFolder) |
179 | c53aa229 | Panagiotis Kanavos | .ToLower(); |
180 | c53aa229 | Panagiotis Kanavos | |
181 | c53aa229 | Panagiotis Kanavos | |
182 | 4ec636f6 | Panagiotis Kanavos | |
183 | 4ec636f6 | Panagiotis Kanavos | var account = accountInfo; |
184 | 5120f3cb | Panagiotis Kanavos | var pendingEntries = from state in FileState.Queryable |
185 | 5120f3cb | Panagiotis Kanavos | where state.FileStatus != FileStatus.Unchanged && |
186 | 77e10b4f | Panagiotis Kanavos | !state.FilePath.StartsWith(cachePath) && |
187 | c53aa229 | Panagiotis Kanavos | !state.FilePath.EndsWith(".ignore") && |
188 | 4ec636f6 | Panagiotis Kanavos | state.FilePath.StartsWith(account.AccountPath) |
189 | 5120f3cb | Panagiotis Kanavos | select state; |
190 | 4ec636f6 | Panagiotis Kanavos | var pendingStates = new List<WorkflowState>(); |
191 | 4ec636f6 | Panagiotis Kanavos | foreach (var state in pendingEntries) |
192 | 4ec636f6 | Panagiotis Kanavos | { |
193 | a0dcfcc9 | Panagiotis Kanavos | pendingStates.Add(new WorkflowState(account, state)); |
194 | 4ec636f6 | Panagiotis Kanavos | } |
195 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
196 | 4ec636f6 | Panagiotis Kanavos | Log.DebugFormat("Found {0} interrupted files", pendingStates.Count); |
197 | 4ec636f6 | Panagiotis Kanavos | |
198 | 4ec636f6 | Panagiotis Kanavos | |
199 | 4ec636f6 | Panagiotis Kanavos | foreach (var entry in pendingStates) |
200 | 4ec636f6 | Panagiotis Kanavos | { |
201 | 4f6d51d4 | Panagiotis Kanavos | Post(entry); |
202 | 5120f3cb | Panagiotis Kanavos | } |
203 | 5120f3cb | Panagiotis Kanavos | } |
204 | 4ec636f6 | Panagiotis Kanavos | } |
205 | 4ec636f6 | Panagiotis Kanavos | |
206 | 9c4346c9 | Panagiotis Kanavos | |
207 | 9c4346c9 | Panagiotis Kanavos | |
208 | 9c4346c9 | Panagiotis Kanavos | public void Post(WorkflowState workflowState) |
209 | 9c4346c9 | Panagiotis Kanavos | { |
210 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
211 | 5120f3cb | Panagiotis Kanavos | Log.DebugFormat("Posted {0} {1} {2}", workflowState.Path, workflowState.Status, workflowState.TriggeringChange); |
212 | 4ec636f6 | Panagiotis Kanavos | |
213 | 4ec636f6 | Panagiotis Kanavos | //Remove invalid state |
214 | 4f6d51d4 | Panagiotis Kanavos | //For now, ignore paths |
215 | 4f6d51d4 | Panagiotis Kanavos | /* if (Directory.Exists(workflowState.Path)) |
216 | 4f6d51d4 | Panagiotis Kanavos | return;*/ |
217 | 4f6d51d4 | Panagiotis Kanavos | //TODO: Need to handle folder renames |
218 | 4ec636f6 | Panagiotis Kanavos | |
219 | 4ec636f6 | Panagiotis Kanavos | Debug.Assert(workflowState.Path.StartsWith(workflowState.AccountInfo.AccountPath, StringComparison.InvariantCultureIgnoreCase), "File from wrong account posted"); |
220 | 4ec636f6 | Panagiotis Kanavos | |
221 | 4ec636f6 | Panagiotis Kanavos | _agent.Post(workflowState); |
222 | 4ec636f6 | Panagiotis Kanavos | } |
223 | 4ec636f6 | Panagiotis Kanavos | |
224 | 9c4346c9 | Panagiotis Kanavos | } |
225 | 9c4346c9 | Panagiotis Kanavos | } |