• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.65
/exist-core/src/main/java/org/exist/storage/lock/FileLockService.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.storage.lock;
25

26
import org.apache.logging.log4j.LogManager;
27
import org.apache.logging.log4j.Logger;
28
import org.exist.EXistException;
29
import org.exist.storage.BrokerPool;
30
import org.exist.storage.BrokerPoolService;
31
import org.exist.storage.BrokerPoolServiceException;
32
import org.exist.util.Configuration;
33
import org.exist.util.ReadOnlyException;
34

35
import java.io.IOException;
36
import java.nio.file.Files;
37
import java.nio.file.Path;
38
import java.nio.file.Paths;
39
import java.util.Optional;
40
import java.util.concurrent.atomic.AtomicReference;
41

42
/**
43
 * A Simple Service wrapper for {@link FileLock}
44
 */
45
public class FileLockService implements BrokerPoolService {
46
    private final static Logger LOG = LogManager.getLogger(FileLockService.class);
1✔
47

48
    private final String lockFileName;
49
    private final String confDirPropName;
50
    private final String defaultDirName;
51

52
    private Path dataDir;
53
    private boolean writable;
54
    private AtomicReference<FileLock> dataLock = new AtomicReference<>();
1✔
55

56
    public FileLockService(final String lockFileName, final String confDirPropName, final String defaultDirName) {
1✔
57
        this.lockFileName = lockFileName;
1✔
58
        this.confDirPropName = confDirPropName;
1✔
59
        this.defaultDirName = defaultDirName;
1✔
60
    }
1✔
61

62
    @Override
63
    public void configure(final Configuration configuration) throws BrokerPoolServiceException {
64
        dataDir = Optional.ofNullable((Path) configuration.getProperty(confDirPropName))
1✔
65
                .orElse(Paths.get(defaultDirName));
1✔
66

67
        if(!Files.exists(dataDir)) {
1!
68
            try {
69
                //TODO : shall we force the creation ? use a parameter to decide ?
70
                LOG.info("Data directory '{}' does not exist. Creating one ...", dataDir.toAbsolutePath().toString());
×
71
                Files.createDirectories(dataDir);
×
72
            } catch(final SecurityException | IOException e) {
×
73
                throw new BrokerPoolServiceException("Cannot create data directory '" + dataDir.toAbsolutePath().toString() + "'", e);
×
74
            }
75
        }
76

77
        //Save it for further use.
78
        configuration.setProperty(confDirPropName, dataDir);
1✔
79

80
        if(!Files.isWritable(dataDir)) {
1!
81
            LOG.warn("Cannot write to data directory: {}", dataDir.toAbsolutePath().toString());
×
82
            writable = false;
×
83
        } else {
×
84
            writable = true;
1✔
85
        }
86
    }
1✔
87

88
    @Override
89
    public void prepare(final BrokerPool brokerPool) throws BrokerPoolServiceException {
90
        // try to acquire lock on the data dir
91
        final FileLock fileLock = new FileLock(brokerPool, dataDir.resolve(lockFileName));
1✔
92
        this.dataLock.compareAndSet(null, fileLock);
1✔
93

94
        try {
95
            final boolean locked = fileLock.tryLock();
1✔
96
            if(!locked) {
1!
97
                throw new BrokerPoolServiceException(new EXistException("The directory seems to be locked by another " +
×
98
                        "database instance. Found a valid lock file: " + fileLock.getFile().toAbsolutePath().toString()));
×
99
            }
100
        } catch(final ReadOnlyException e) {
×
101
            LOG.warn(e);
×
102
            writable = false;
×
103
        }
104

105
        if(!writable) {
1!
106
            brokerPool.setReadOnly();
×
107
        }
108
    }
1✔
109

110
    /**
111
     * Is this directory managed by this File Lock read-only?
112
     *
113
     * @return true if the directory is read-only
114
     */
115
    public boolean isReadOnly() {
116
        return !writable;
×
117
    }
118

119
    public Path getFile() {
120
        final FileLock fileLock = dataLock.get();
1✔
121
        if(fileLock == null) {
1!
122
            return null;
×
123
        } else {
124
            return fileLock.getFile();
1✔
125
        }
126
    }
127

128
    //TODO(AR) instead we should implement a BrokerPoolService#shutdown() and BrokerPoolServicesManager#shutdown()
129
    public void release() {
130
        final FileLock fileLock = dataLock.get();
1✔
131
        if(fileLock != null) {
1!
132
            fileLock.release();
1✔
133
        }
134
        dataLock.compareAndSet(fileLock, null);
1✔
135
    }
1✔
136
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc