Statistics
| Branch: | Revision:

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
}