root / trunk / Pithos.Core / Agents / WorkflowAgent.cs @ 4f6d51d4
History | View | Annotate | Download (6.4 kB)
1 | 9c4346c9 | Panagiotis Kanavos | using System; |
---|---|---|---|
2 | 9c4346c9 | Panagiotis Kanavos | using System.Collections.Generic; |
3 | 9c4346c9 | Panagiotis Kanavos | using System.ComponentModel.Composition; |
4 | 9c4346c9 | Panagiotis Kanavos | using System.Diagnostics; |
5 | 9c4346c9 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
6 | 9c4346c9 | Panagiotis Kanavos | using System.IO; |
7 | 9c4346c9 | Panagiotis Kanavos | using System.Linq; |
8 | 9c4346c9 | Panagiotis Kanavos | using System.Text; |
9 | a64c87c8 | Panagiotis Kanavos | using System.Threading.Tasks; |
10 | 9c4346c9 | Panagiotis Kanavos | using Pithos.Interfaces; |
11 | c53aa229 | Panagiotis Kanavos | using Pithos.Network; |
12 | 5120f3cb | Panagiotis Kanavos | using log4net; |
13 | 9c4346c9 | Panagiotis Kanavos | |
14 | 9c4346c9 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
15 | 9c4346c9 | Panagiotis Kanavos | { |
16 | 9c4346c9 | Panagiotis Kanavos | [Export] |
17 | 9c4346c9 | Panagiotis Kanavos | public class WorkflowAgent |
18 | 9c4346c9 | Panagiotis Kanavos | { |
19 | 4ec636f6 | Panagiotis Kanavos | Agent<WorkflowState> _agent; |
20 | 9c4346c9 | Panagiotis Kanavos | |
21 | 9c4346c9 | Panagiotis Kanavos | public IStatusNotification StatusNotification { get; set; } |
22 | 9c4346c9 | Panagiotis Kanavos | [Import] |
23 | 9c4346c9 | Panagiotis Kanavos | public IStatusKeeper StatusKeeper { get; set; } |
24 | 5ce54458 | Panagiotis Kanavos | |
25 | 9c4346c9 | Panagiotis Kanavos | [Import] |
26 | 9c4346c9 | Panagiotis Kanavos | public NetworkAgent NetworkAgent { get; set; } |
27 | 9c4346c9 | Panagiotis Kanavos | |
28 | 5120f3cb | Panagiotis Kanavos | private static readonly ILog Log = LogManager.GetLogger("WorkflowAgent"); |
29 | 5120f3cb | Panagiotis Kanavos | |
30 | 9c4346c9 | Panagiotis Kanavos | public void Start() |
31 | 9c4346c9 | Panagiotis Kanavos | { |
32 | 4ec636f6 | Panagiotis Kanavos | _agent = Agent<WorkflowState>.Start(inbox => |
33 | 9c4346c9 | Panagiotis Kanavos | { |
34 | 9c4346c9 | Panagiotis Kanavos | Action loop = null; |
35 | 9c4346c9 | Panagiotis Kanavos | loop = () => |
36 | 9c4346c9 | Panagiotis Kanavos | { |
37 | 4ec636f6 | Panagiotis Kanavos | var message = inbox.Receive(); |
38 | a64c87c8 | Panagiotis Kanavos | var process = message.Then(Process, inbox.CancellationToken); |
39 | a64c87c8 | Panagiotis Kanavos | inbox.LoopAsync(process,loop,ex=> |
40 | 5120f3cb | Panagiotis Kanavos | Log.ErrorFormat("[ERROR] Synch for {0}:\r{1}", message.Result.FileName, ex)); |
41 | 9c4346c9 | Panagiotis Kanavos | }; |
42 | 9c4346c9 | Panagiotis Kanavos | loop(); |
43 | 4ec636f6 | Panagiotis Kanavos | }); |
44 | 9c4346c9 | Panagiotis Kanavos | } |
45 | 9c4346c9 | Panagiotis Kanavos | |
46 | 4ec636f6 | Panagiotis Kanavos | private Task<object> Process(WorkflowState state) |
47 | a64c87c8 | Panagiotis Kanavos | { |
48 | c53aa229 | Panagiotis Kanavos | var accountInfo = state.AccountInfo; |
49 | 5120f3cb | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["Workflow"].Push("Process")) |
50 | a64c87c8 | Panagiotis Kanavos | { |
51 | a0dcfcc9 | Panagiotis Kanavos | try |
52 | 5120f3cb | Panagiotis Kanavos | { |
53 | 5120f3cb | Panagiotis Kanavos | |
54 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
55 | a0dcfcc9 | Panagiotis Kanavos | Log.DebugFormat("State {0} {1} {2}", state.FileName, state.Status, state.TriggeringChange); |
56 | a0dcfcc9 | Panagiotis Kanavos | |
57 | a0dcfcc9 | Panagiotis Kanavos | if (state.Skip) |
58 | a0dcfcc9 | Panagiotis Kanavos | { |
59 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("Skipping {0}", state.FileName); |
60 | a0dcfcc9 | Panagiotis Kanavos | |
61 | a0dcfcc9 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
62 | a0dcfcc9 | Panagiotis Kanavos | } |
63 | a0dcfcc9 | Panagiotis Kanavos | string path = state.Path.ToLower(); |
64 | a0dcfcc9 | Panagiotis Kanavos | |
65 | 4f6d51d4 | Panagiotis Kanavos | |
66 | 4f6d51d4 | Panagiotis Kanavos | |
67 | 4f6d51d4 | Panagiotis Kanavos | FileSystemInfo info = Directory.Exists(path) ? (FileSystemInfo) new DirectoryInfo(path) : new FileInfo(path); |
68 | 4f6d51d4 | Panagiotis Kanavos | |
69 | a0dcfcc9 | Panagiotis Kanavos | //Bypass deleted files, unless the status is Deleted |
70 | 4f6d51d4 | Panagiotis Kanavos | if (!info.Exists && state.Status != FileStatus.Deleted) |
71 | a0dcfcc9 | Panagiotis Kanavos | { |
72 | a0dcfcc9 | Panagiotis Kanavos | state.Skip = true; |
73 | a0dcfcc9 | Panagiotis Kanavos | this.StatusKeeper.ClearFileStatus(path); |
74 | a0dcfcc9 | Panagiotis Kanavos | |
75 | a0dcfcc9 | Panagiotis Kanavos | if (Log.IsDebugEnabled) Log.DebugFormat("Skipped missing {0}", state.FileName); |
76 | a0dcfcc9 | Panagiotis Kanavos | |
77 | a0dcfcc9 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
78 | a0dcfcc9 | Panagiotis Kanavos | } |
79 | a0dcfcc9 | Panagiotis Kanavos | |
80 | a0dcfcc9 | Panagiotis Kanavos | var fileState = FileState.FindByFilePath(path); |
81 | a0dcfcc9 | Panagiotis Kanavos | |
82 | a0dcfcc9 | Panagiotis Kanavos | |
83 | a0dcfcc9 | Panagiotis Kanavos | switch (state.Status) |
84 | a0dcfcc9 | Panagiotis Kanavos | { |
85 | a0dcfcc9 | Panagiotis Kanavos | case FileStatus.Created: |
86 | a0dcfcc9 | Panagiotis Kanavos | case FileStatus.Modified: |
87 | a0dcfcc9 | Panagiotis Kanavos | NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState, accountInfo.BlockSize, |
88 | a0dcfcc9 | Panagiotis Kanavos | accountInfo.BlockHash)); |
89 | a0dcfcc9 | Panagiotis Kanavos | break; |
90 | a0dcfcc9 | Panagiotis Kanavos | case FileStatus.Deleted: |
91 | a0dcfcc9 | Panagiotis Kanavos | NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState)); |
92 | a0dcfcc9 | Panagiotis Kanavos | break; |
93 | a0dcfcc9 | Panagiotis Kanavos | case FileStatus.Renamed: |
94 | 4f6d51d4 | Panagiotis Kanavos | FileSystemInfo oldInfo = Directory.Exists(state.OldPath) ? (FileSystemInfo)new DirectoryInfo(state.OldPath) : new FileInfo(state.OldPath); |
95 | 4f6d51d4 | Panagiotis Kanavos | FileSystemInfo newInfo = Directory.Exists(state.Path) ? (FileSystemInfo)new DirectoryInfo(state.Path) : new FileInfo(state.Path); |
96 | a0dcfcc9 | Panagiotis Kanavos | NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud, |
97 | 4f6d51d4 | Panagiotis Kanavos | oldInfo, |
98 | 4f6d51d4 | Panagiotis Kanavos | newInfo)); |
99 | a0dcfcc9 | Panagiotis Kanavos | break; |
100 | a0dcfcc9 | Panagiotis Kanavos | } |
101 | 5120f3cb | Panagiotis Kanavos | |
102 | 4ec636f6 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
103 | 5120f3cb | Panagiotis Kanavos | } |
104 | a0dcfcc9 | Panagiotis Kanavos | catch (Exception ex) |
105 | 5120f3cb | Panagiotis Kanavos | { |
106 | a0dcfcc9 | Panagiotis Kanavos | Log.Error(ex.ToString()); |
107 | a0dcfcc9 | Panagiotis Kanavos | throw; |
108 | 5120f3cb | Panagiotis Kanavos | } |
109 | 5120f3cb | Panagiotis Kanavos | } |
110 | a64c87c8 | Panagiotis Kanavos | } |
111 | a64c87c8 | Panagiotis Kanavos | |
112 | a64c87c8 | Panagiotis Kanavos | |
113 | c53aa229 | Panagiotis Kanavos | //Starts interrupted files for a specific account |
114 | c53aa229 | Panagiotis Kanavos | public void RestartInterruptedFiles(AccountInfo accountInfo) |
115 | 9c4346c9 | Panagiotis Kanavos | { |
116 | 5ce54458 | Panagiotis Kanavos | |
117 | 5120f3cb | Panagiotis Kanavos | StatusNotification.NotifyChange("Restart processing interrupted files", TraceLevel.Verbose); |
118 | 9c4346c9 | Panagiotis Kanavos | |
119 | 5120f3cb | Panagiotis Kanavos | using (log4net.ThreadContext.Stacks["Workflow"].Push("Restart")) |
120 | 5120f3cb | Panagiotis Kanavos | { |
121 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
122 | 5120f3cb | Panagiotis Kanavos | Log.Debug("Starting interrupted files"); |
123 | c53aa229 | Panagiotis Kanavos | |
124 | 77e10b4f | Panagiotis Kanavos | var cachePath = Path.Combine(accountInfo.AccountPath, FolderConstants.CacheFolder) |
125 | c53aa229 | Panagiotis Kanavos | .ToLower(); |
126 | c53aa229 | Panagiotis Kanavos | |
127 | c53aa229 | Panagiotis Kanavos | |
128 | 4ec636f6 | Panagiotis Kanavos | |
129 | 4ec636f6 | Panagiotis Kanavos | var account = accountInfo; |
130 | 5120f3cb | Panagiotis Kanavos | var pendingEntries = from state in FileState.Queryable |
131 | 5120f3cb | Panagiotis Kanavos | where state.FileStatus != FileStatus.Unchanged && |
132 | 77e10b4f | Panagiotis Kanavos | !state.FilePath.StartsWith(cachePath) && |
133 | c53aa229 | Panagiotis Kanavos | !state.FilePath.EndsWith(".ignore") && |
134 | 4ec636f6 | Panagiotis Kanavos | state.FilePath.StartsWith(account.AccountPath) |
135 | 5120f3cb | Panagiotis Kanavos | select state; |
136 | 4ec636f6 | Panagiotis Kanavos | var pendingStates = new List<WorkflowState>(); |
137 | 4ec636f6 | Panagiotis Kanavos | foreach (var state in pendingEntries) |
138 | 4ec636f6 | Panagiotis Kanavos | { |
139 | a0dcfcc9 | Panagiotis Kanavos | pendingStates.Add(new WorkflowState(account, state)); |
140 | 4ec636f6 | Panagiotis Kanavos | } |
141 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
142 | 4ec636f6 | Panagiotis Kanavos | Log.DebugFormat("Found {0} interrupted files", pendingStates.Count); |
143 | 4ec636f6 | Panagiotis Kanavos | |
144 | 4ec636f6 | Panagiotis Kanavos | |
145 | 4ec636f6 | Panagiotis Kanavos | foreach (var entry in pendingStates) |
146 | 4ec636f6 | Panagiotis Kanavos | { |
147 | 4f6d51d4 | Panagiotis Kanavos | Post(entry); |
148 | 5120f3cb | Panagiotis Kanavos | } |
149 | 5120f3cb | Panagiotis Kanavos | } |
150 | 4ec636f6 | Panagiotis Kanavos | } |
151 | 4ec636f6 | Panagiotis Kanavos | |
152 | 9c4346c9 | Panagiotis Kanavos | |
153 | 9c4346c9 | Panagiotis Kanavos | |
154 | 9c4346c9 | Panagiotis Kanavos | public void Post(WorkflowState workflowState) |
155 | 9c4346c9 | Panagiotis Kanavos | { |
156 | 5120f3cb | Panagiotis Kanavos | if (Log.IsDebugEnabled) |
157 | 5120f3cb | Panagiotis Kanavos | Log.DebugFormat("Posted {0} {1} {2}", workflowState.Path, workflowState.Status, workflowState.TriggeringChange); |
158 | 4ec636f6 | Panagiotis Kanavos | |
159 | 4ec636f6 | Panagiotis Kanavos | //Remove invalid state |
160 | 4f6d51d4 | Panagiotis Kanavos | //For now, ignore paths |
161 | 4f6d51d4 | Panagiotis Kanavos | /* if (Directory.Exists(workflowState.Path)) |
162 | 4f6d51d4 | Panagiotis Kanavos | return;*/ |
163 | 4f6d51d4 | Panagiotis Kanavos | //TODO: Need to handle folder renames |
164 | 4ec636f6 | Panagiotis Kanavos | |
165 | 4ec636f6 | Panagiotis Kanavos | Debug.Assert(workflowState.Path.StartsWith(workflowState.AccountInfo.AccountPath, StringComparison.InvariantCultureIgnoreCase), "File from wrong account posted"); |
166 | 4ec636f6 | Panagiotis Kanavos | |
167 | 4ec636f6 | Panagiotis Kanavos | _agent.Post(workflowState); |
168 | 4ec636f6 | Panagiotis Kanavos | } |
169 | 4ec636f6 | Panagiotis Kanavos | |
170 | 9c4346c9 | Panagiotis Kanavos | } |
171 | 9c4346c9 | Panagiotis Kanavos | } |