Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / NetworkGate.cs @ 78ebfd2d

History | View | Annotate | Download (6.4 kB)

1 f3d080df Panagiotis Kanavos
// -----------------------------------------------------------------------
2 f3d080df Panagiotis Kanavos
// <copyright file="NetworkGate.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 1caef52e Panagiotis Kanavos
using System;
39 1caef52e Panagiotis Kanavos
using System.Collections.Concurrent;
40 1caef52e Panagiotis Kanavos
using System.Collections.Generic;
41 1caef52e Panagiotis Kanavos
using System.Diagnostics.Contracts;
42 1caef52e Panagiotis Kanavos
using System.IO;
43 1caef52e Panagiotis Kanavos
44 1caef52e Panagiotis Kanavos
namespace Pithos.Core
45 1caef52e Panagiotis Kanavos
{
46 1caef52e Panagiotis Kanavos
    public enum NetworkOperation
47 1caef52e Panagiotis Kanavos
    {
48 1caef52e Panagiotis Kanavos
        None,
49 1caef52e Panagiotis Kanavos
        Uploading,
50 f3d080df Panagiotis Kanavos
        Downloading,
51 f3d080df Panagiotis Kanavos
        Deleting,
52 f3d080df Panagiotis Kanavos
        Renaming
53 1caef52e Panagiotis Kanavos
    }
54 1caef52e Panagiotis Kanavos
55 1caef52e Panagiotis Kanavos
    //The NetworkGate prevents starting download/uploads for files that are already in the process of downloading,
56 1caef52e Panagiotis Kanavos
    //uploading.   
57 1caef52e Panagiotis Kanavos
    public class NetworkGate:IDisposable
58 1caef52e Panagiotis Kanavos
    {
59 cfed7823 Panagiotis Kanavos
        public string FilePath { get; private set; }
60 cfed7823 Panagiotis Kanavos
        public NetworkOperation Operation { get; private set; }
61 cfed7823 Panagiotis Kanavos
62 cfed7823 Panagiotis Kanavos
        [ContractInvariantMethod]
63 cfed7823 Panagiotis Kanavos
        private void Invariants()
64 cfed7823 Panagiotis Kanavos
        {
65 cfed7823 Panagiotis Kanavos
            Contract.Invariant(!String.IsNullOrWhiteSpace(FilePath));
66 cfed7823 Panagiotis Kanavos
            Contract.Invariant(Path.IsPathRooted(FilePath));
67 cfed7823 Panagiotis Kanavos
        }
68 cfed7823 Panagiotis Kanavos
69 1caef52e Panagiotis Kanavos
        //The state of each file is stored in a thread-safe dictionary
70 1caef52e Panagiotis Kanavos
        static readonly ConcurrentDictionary<string, NetworkOperation> NetworkState = new ConcurrentDictionary<string, NetworkOperation>();
71 1caef52e Panagiotis Kanavos
72 1caef52e Panagiotis Kanavos
        public static NetworkOperation GetNetworkState(string path)
73 1caef52e Panagiotis Kanavos
        {
74 1caef52e Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
75 1caef52e Panagiotis Kanavos
                throw new ArgumentNullException("path");
76 1caef52e Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
77 1caef52e Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "path");
78 1caef52e Panagiotis Kanavos
            Contract.EndContractBlock();
79 1caef52e Panagiotis Kanavos
80 1caef52e Panagiotis Kanavos
            NetworkOperation operation;
81 f3d080df Panagiotis Kanavos
            var lower = path.ToLower();
82 f3d080df Panagiotis Kanavos
            if (NetworkState.TryGetValue(lower, out operation))
83 1caef52e Panagiotis Kanavos
                return operation;
84 1caef52e Panagiotis Kanavos
            return NetworkOperation.None;
85 1caef52e Panagiotis Kanavos
        }
86 1caef52e Panagiotis Kanavos
87 1caef52e Panagiotis Kanavos
        //Store a network operation for the specified path
88 1caef52e Panagiotis Kanavos
        public static void SetNetworkState(string path, NetworkOperation operation)
89 1caef52e Panagiotis Kanavos
        {
90 1caef52e Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
91 1caef52e Panagiotis Kanavos
                throw new ArgumentNullException("path");
92 1caef52e Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
93 1caef52e Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "path");
94 1caef52e Panagiotis Kanavos
            Contract.EndContractBlock();
95 1caef52e Panagiotis Kanavos
96 1caef52e Panagiotis Kanavos
            var lower = path.ToLower();
97 1caef52e Panagiotis Kanavos
            NetworkState[lower] = operation;            
98 1caef52e Panagiotis Kanavos
            //By default, None values don't need to be stored. They are stored anyway
99 1caef52e Panagiotis Kanavos
            //because TryRemove may fail.
100 1caef52e Panagiotis Kanavos
            if (operation == NetworkOperation.None)
101 1caef52e Panagiotis Kanavos
            {
102 1caef52e Panagiotis Kanavos
                NetworkOperation oldOperation;
103 1caef52e Panagiotis Kanavos
                NetworkState.TryRemove(lower, out oldOperation);
104 1caef52e Panagiotis Kanavos
            }
105 1caef52e Panagiotis Kanavos
        }
106 1caef52e Panagiotis Kanavos
107 1caef52e Panagiotis Kanavos
        //Clients should acquire a NetworkGate before starting any network operation.
108 1caef52e Panagiotis Kanavos
        //If Acquire fails, another network operation is already in progress
109 1caef52e Panagiotis Kanavos
        public static NetworkGate Acquire(string path, NetworkOperation operation)
110 1caef52e Panagiotis Kanavos
        {
111 1caef52e Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
112 1caef52e Panagiotis Kanavos
                throw new ArgumentNullException("path");
113 1caef52e Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
114 1caef52e Panagiotis Kanavos
                throw new ArgumentException("path must be a rooted path", "path");
115 1caef52e Panagiotis Kanavos
            Contract.EndContractBlock();
116 1caef52e Panagiotis Kanavos
117 f3d080df Panagiotis Kanavos
            var lower = path.ToLower();
118 f3d080df Panagiotis Kanavos
            var state = GetNetworkState(lower);
119 1caef52e Panagiotis Kanavos
            //If no operation is in progress, return a NetworkGate
120 1caef52e Panagiotis Kanavos
            return (state == NetworkOperation.None)
121 f3d080df Panagiotis Kanavos
                       ? new NetworkGate(lower, operation)
122 1caef52e Panagiotis Kanavos
                   //otherwise return a gate with Fail flagged
123 f3d080df Panagiotis Kanavos
                       : new NetworkGate(lower, NetworkOperation.None);
124 1caef52e Panagiotis Kanavos
        }
125 1caef52e Panagiotis Kanavos
126 1caef52e Panagiotis Kanavos
127 1caef52e Panagiotis Kanavos
128 cfed7823 Panagiotis Kanavos
129 cfed7823 Panagiotis Kanavos
130 1caef52e Panagiotis Kanavos
131 1caef52e Panagiotis Kanavos
        private NetworkGate(string path,NetworkOperation operation)
132 1caef52e Panagiotis Kanavos
        {
133 1caef52e Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(path))
134 1caef52e Panagiotis Kanavos
                throw new ArgumentNullException("path");
135 cfed7823 Panagiotis Kanavos
            if (!Path.IsPathRooted(path))
136 cfed7823 Panagiotis Kanavos
                throw new ArgumentException("path must be rooted","path");
137 1caef52e Panagiotis Kanavos
            Contract.EndContractBlock();
138 1caef52e Panagiotis Kanavos
139 1caef52e Panagiotis Kanavos
            Operation = operation;
140 cfed7823 Panagiotis Kanavos
            FilePath = path.ToLower();            
141 1caef52e Panagiotis Kanavos
142 1caef52e Panagiotis Kanavos
            //Skip dummy operations (those with Operation == None)
143 1caef52e Panagiotis Kanavos
            if (Operation != NetworkOperation.None)
144 1caef52e Panagiotis Kanavos
                //and store the file's operation
145 1caef52e Panagiotis Kanavos
                SetNetworkState(FilePath, operation);
146 1caef52e Panagiotis Kanavos
        }
147 1caef52e Panagiotis Kanavos
148 1caef52e Panagiotis Kanavos
        //A NetworkGate has Failed if its operation is None
149 1caef52e Panagiotis Kanavos
        public bool Failed { get { return Operation == NetworkOperation.None; } }
150 1caef52e Panagiotis Kanavos
151 1caef52e Panagiotis Kanavos
        //Release a gate by setting the NetworkOperation to None
152 1caef52e Panagiotis Kanavos
        public void Release()
153 1caef52e Panagiotis Kanavos
        {
154 1caef52e Panagiotis Kanavos
            //Skip Failed flags
155 1caef52e Panagiotis Kanavos
            if (!Failed)
156 1caef52e Panagiotis Kanavos
                //And reset the operation state for the file
157 1caef52e Panagiotis Kanavos
                SetNetworkState(FilePath,NetworkOperation.None);
158 1caef52e Panagiotis Kanavos
        }
159 1caef52e Panagiotis Kanavos
160 1caef52e Panagiotis Kanavos
161 1caef52e Panagiotis Kanavos
        public void Dispose()
162 1caef52e Panagiotis Kanavos
        {
163 1caef52e Panagiotis Kanavos
            Dispose(true);
164 1caef52e Panagiotis Kanavos
            GC.SuppressFinalize(this);
165 1caef52e Panagiotis Kanavos
        }
166 1caef52e Panagiotis Kanavos
167 1caef52e Panagiotis Kanavos
        protected void Dispose(bool disposing)
168 1caef52e Panagiotis Kanavos
        {
169 1caef52e Panagiotis Kanavos
            if (disposing)
170 1caef52e Panagiotis Kanavos
            {
171 1caef52e Panagiotis Kanavos
                Release();
172 1caef52e Panagiotis Kanavos
            }
173 1caef52e Panagiotis Kanavos
        }
174 1caef52e Panagiotis Kanavos
175 1caef52e Panagiotis Kanavos
    }
176 1caef52e Panagiotis Kanavos
}