This project has retired. For details please refer to its
Attic page.
DefaultFileLockManager xref
1 package org.apache.archiva.common.filelock;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.lang3.time.StopWatch;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.springframework.stereotype.Service;
26
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.nio.channels.ClosedChannelException;
30 import java.nio.file.Files;
31 import java.nio.file.NoSuchFileException;
32 import java.nio.file.Path;
33 import java.util.concurrent.ConcurrentHashMap;
34 import java.util.concurrent.ConcurrentMap;
35
36
37
38
39
40 @Service("fileLockManager#default")
41 public class DefaultFileLockManager
42 implements FileLockManager
43 {
44
45
46
47 private static final ConcurrentMap<Path, Lock> lockFiles = new ConcurrentHashMap<Path, Lock>( 64 );
48
49 private boolean skipLocking = true;
50
51 private Logger log = LoggerFactory.getLogger( getClass() );
52
53 private int timeout = 0;
54
55
56 @Override
57 public Lock readFileLock( Path file )
58 throws FileLockException, FileLockTimeoutException
59 {
60 if ( skipLocking )
61 {
62 return new Lock( file );
63
64 }
65 StopWatch stopWatch = new StopWatch();
66 boolean acquired = false;
67 try {
68 mkdirs(file.getParent());
69 } catch (IOException e) {
70 throw new FileLockException("Could not create directories "+file.getParent(), e);
71 }
72
73 Lock lock = null;
74
75 stopWatch.start();
76
77 while ( !acquired )
78 {
79
80 lock = null;
81
82 if ( timeout > 0 )
83 {
84 long delta = stopWatch.getTime();
85 log.debug( "delta {}, timeout {}", delta, timeout );
86 if ( delta > timeout )
87 {
88 log.warn( "Cannot acquire read lock within {} millis. Will skip the file: {}", timeout, file );
89
90 throw new FileLockTimeoutException();
91 }
92 }
93
94 Lock current = lockFiles.get( file );
95
96 if ( current != null )
97 {
98 log.trace( "read lock file exist continue wait" );
99 continue;
100 }
101
102 try
103 {
104 lock = new Lock( file, false );
105 createNewFileQuietly( file );
106 lock.openLock( false, timeout > 0 );
107
108
109
110
111
112
113 current = lockFiles.putIfAbsent( file, lock );
114 if ( current == null )
115 {
116
117 acquired = true;
118 } else {
119
120 lock.close();
121 lock=null;
122 }
123 }
124 catch ( FileNotFoundException | NoSuchFileException e )
125 {
126
127 log.debug( "read Lock skip: {} try to create file", e.getMessage() );
128 createNewFileQuietly( file );
129 }
130 catch ( IOException e )
131 {
132 throw new FileLockException( e.getMessage(), e );
133 }
134 catch ( IllegalStateException e )
135 {
136 log.trace( "openLock {}:{}", e.getClass(), e.getMessage() );
137 }
138 }
139
140 return lock;
141
142 }
143
144
145 @Override
146 public Lock writeFileLock( Path file )
147 throws FileLockException, FileLockTimeoutException
148 {
149 if ( skipLocking )
150 {
151 return new Lock( file );
152 }
153
154 try {
155 mkdirs( file.getParent() );
156 } catch (IOException e) {
157 throw new FileLockException("Could not create directory "+file.getParent(), e);
158 }
159
160 StopWatch stopWatch = new StopWatch();
161 boolean acquired = false;
162
163 Lock lock = null;
164
165 stopWatch.start();
166
167 while ( !acquired )
168 {
169
170 lock = null;
171 if ( timeout > 0 )
172 {
173 long delta = stopWatch.getTime();
174 log.debug( "delta {}, timeout {}", delta, timeout );
175 if ( delta > timeout )
176 {
177 log.warn( "Cannot acquire read lock within {} millis. Will skip the file: {}", timeout, file );
178
179 throw new FileLockTimeoutException();
180 }
181 }
182
183 Lock current = lockFiles.get( file );
184
185 try
186 {
187
188 if ( current != null )
189 {
190 log.trace( "write lock file exist continue wait" );
191
192 continue;
193 }
194 lock = new Lock( file, true );
195 createNewFileQuietly( file );
196 lock.openLock( true, timeout > 0 );
197
198
199
200
201
202
203 current = lockFiles.putIfAbsent( file, lock );
204 if ( current == null )
205 {
206
207 acquired = true;
208 } else {
209
210 lock.close();
211 lock=null;
212 }
213 }
214 catch ( FileNotFoundException | NoSuchFileException e )
215 {
216
217 log.debug( "write Lock skip: {} try to create file", e.getMessage() );
218 createNewFileQuietly( file );
219 }
220 catch ( IOException e )
221 {
222 throw new FileLockException( e.getMessage(), e );
223 }
224 catch ( IllegalStateException e )
225 {
226 log.trace( "openLock {}:{}", e.getClass(), e.getMessage() );
227 }
228 }
229
230 return lock;
231
232
233 }
234
235 private void createNewFileQuietly( Path file )
236 {
237 try
238 {
239 Files.createFile(file);
240 }
241 catch ( IOException e )
242 {
243
244 }
245 }
246
247 @Override
248 public void release( Lock lock )
249 throws FileLockException
250 {
251 if ( lock == null )
252 {
253 log.debug( "skip releasing null" );
254 return;
255 }
256 if ( skipLocking )
257 {
258 return;
259 }
260 try
261 {
262 lockFiles.remove( lock.getFile() );
263 lock.close();
264 }
265 catch ( ClosedChannelException e )
266 {
267
268 log.debug( "ignore ClosedChannelException: {}", e.getMessage() );
269 }
270 catch ( IOException e )
271 {
272 throw new FileLockException( e.getMessage(), e );
273 }
274 }
275
276 @Override
277 public void clearLockFiles()
278 {
279 lockFiles.clear();
280 }
281
282 private Path mkdirs( Path directory ) throws IOException {
283 return Files.createDirectories(directory);
284 }
285
286 @Override
287 public int getTimeout()
288 {
289 return timeout;
290 }
291
292 @Override
293 public void setTimeout( int timeout )
294 {
295 this.timeout = timeout;
296 }
297
298 @Override
299 public boolean isSkipLocking()
300 {
301 return skipLocking;
302 }
303
304 @Override
305 public void setSkipLocking( boolean skipLocking )
306 {
307 this.skipLocking = skipLocking;
308 }
309 }