Statistics
| Branch: | Revision:

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
}