use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.
the class NativeBroker method getXMLResource.
@Override
public LockedDocument getXMLResource(XmldbURI fileName, final LockMode lockMode) throws PermissionDeniedException {
if (fileName == null) {
return null;
}
fileName = prepend(fileName.toCollectionPathURI());
// TODO : resolve URIs !
final XmldbURI collUri = fileName.removeLastSegment();
final XmldbURI docUri = fileName.lastSegment();
final LockMode collectionLockMode = lockManager.relativeCollectionLockMode(LockMode.READ_LOCK, lockMode);
try (final Collection collection = openCollection(collUri, collectionLockMode)) {
if (collection == null) {
LOG.debug("Collection '{}' not found!", collUri);
return null;
}
try {
// if (!collection.getPermissions().validate(getCurrentSubject(), Permission.EXECUTE)) {
// throw new PermissionDeniedException("Permission denied to read collection '" + collUri + "' by " + getCurrentSubject().getName());
// }
final LockedDocument lockedDocument = collection.getDocumentWithLock(this, docUri, lockMode);
// NOTE: early release of Collection lock inline with Asymmetrical Locking scheme
collection.close();
if (lockedDocument == null) {
// LOG.debug("document '" + fileName + "' not found!");
return null;
}
// if (!doc.getMode().validate(getUser(), Permission.READ))
// throw new PermissionDeniedException("not allowed to read document");
final DocumentImpl doc = lockedDocument.getDocument();
return lockedDocument;
} catch (final LockException e) {
LOG.error("Could not acquire lock on document {}", fileName, e);
// TODO : exception ? -pb
}
}
return null;
}
use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.
the class RpcConnection method beginProtected.
protected LockedDocumentMap beginProtected(final DBBroker broker, final Map<String, Object> parameters) throws EXistException, PermissionDeniedException {
final String protectColl = (String) parameters.get(RpcAPI.PROTECTED_MODE);
if (protectColl == null) {
return null;
}
int retries = BEGIN_PROTECTED_MAX_LOCKING_RETRIES == -1 ? -1 : BEGIN_PROTECTED_MAX_LOCKING_RETRIES - 2;
do {
MutableDocumentSet docs = null;
final LockedDocumentMap lockedDocuments = new LockedDocumentMap();
final LockMode documentLockMode = LockMode.WRITE_LOCK;
final LockMode collectionLockMode = broker.getBrokerPool().getLockManager().relativeCollectionLockMode(LockMode.READ_LOCK, documentLockMode);
try (final Collection coll = broker.openCollection(XmldbURI.createInternal(protectColl), collectionLockMode)) {
docs = new DefaultDocumentSet();
coll.allDocs(broker, docs, true, lockedDocuments, documentLockMode);
return lockedDocuments;
} catch (final LockException e) {
LOG.warn("Deadlock detected. Starting over again. Docs: {}; locked: {}. Cause: {}", docs.getDocumentCount(), lockedDocuments.size(), e.getMessage());
lockedDocuments.unlock();
}
retries--;
} while (retries >= -1);
throw new EXistException("Unable to beginProtected after " + BEGIN_PROTECTED_MAX_LOCKING_RETRIES + " retries");
}
use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.
the class DocUtils method getDocumentByPathFromDB.
private static Sequence getDocumentByPathFromDB(final XQueryContext context, final String path) throws XPathException, PermissionDeniedException {
// check if the loaded documents should remain locked
final LockMode lockType = context.lockDocumentsOnLoad() ? LockMode.WRITE_LOCK : LockMode.READ_LOCK;
try {
final XmldbURI baseURI = context.getBaseURI().toXmldbURI();
final XmldbURI pathUri;
if (baseURI != null && !(baseURI.equals("") || baseURI.equals("/db"))) {
// relative collection Path: add the current base URI
pathUri = baseURI.resolveCollectionPath(XmldbURI.xmldbUriFor(path, false));
} else {
pathUri = XmldbURI.xmldbUriFor(path, false);
}
// relative collection Path: add the current module call URI if applicable
final XmldbURI resourceUri = Optional.ofNullable(context.getModuleLoadPath()).filter(moduleLoadPath -> !moduleLoadPath.isEmpty()).flatMap(moduleLoadPath -> Try(() -> XmldbURI.xmldbUriFor(moduleLoadPath)).toOption()).map(moduleLoadPath -> moduleLoadPath.resolveCollectionPath(pathUri)).orElse(pathUri);
// try to open the document and acquire a lock
try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(resourceUri, lockType)) {
if (lockedDoc == null) {
return Sequence.EMPTY_SEQUENCE;
} else {
final DocumentImpl doc = lockedDoc.getDocument();
if (!doc.getPermissions().validate(context.getSubject(), Permission.READ)) {
throw new PermissionDeniedException("Insufficient privileges to read resource " + path);
}
if (doc.getResourceType() == DocumentImpl.BINARY_FILE) {
throw new XPathException("Document " + path + " is a binary resource, not an XML document. Please consider using the function util:binary-doc() to retrieve a reference to it.");
}
return new NodeProxy(doc);
}
}
} catch (final URISyntaxException e) {
throw new XPathException(e);
}
}
use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.
the class LockTableUtils method stateToXml.
public static void stateToXml(final LockTable lockTable, final boolean includeStack, final Writer writer) throws XMLStreamException {
final GregorianCalendar cal = new GregorianCalendar();
final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
final XMLStreamWriter xmlWriter = outputFactory.createXMLStreamWriter(writer);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("lock-table");
final XMLGregorianCalendar xmlCal = TimeUtils.getInstance().newXMLGregorianCalendar(cal);
xmlWriter.writeAttribute("timestamp", xmlCal.toXMLFormat());
// acquired locks
xmlWriter.writeStartElement("acquired");
for (final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
xmlWriter.writeStartElement("lock");
xmlWriter.writeAttribute("id", acquire.getKey());
for (final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
xmlWriter.writeStartElement("type");
xmlWriter.writeAttribute("id", type.getKey().name());
for (final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
xmlWriter.writeStartElement("mode");
xmlWriter.writeAttribute("id", lockModeOwners.getKey().name());
for (final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
xmlWriter.writeStartElement("thread");
xmlWriter.writeAttribute("id", ownerHoldCount.getKey());
final LockCountTraces holdCount = ownerHoldCount.getValue();
xmlWriter.writeAttribute("hold-count", Integer.toString(holdCount.count));
if (holdCount.traces != null && includeStack) {
for (int i = 0; i < holdCount.traces.size(); i++) {
xmlWriter.writeStartElement("stack-trace");
xmlWriter.writeAttribute("index", Integer.toString(i));
final StackTraceElement[] trace = holdCount.traces.get(i);
for (int j = 0; j < trace.length; j++) {
xmlWriter.writeStartElement("call");
final StackTraceElement call = trace[j];
xmlWriter.writeAttribute("index", Integer.toString(j));
xmlWriter.writeAttribute("class", call.getClassName());
xmlWriter.writeAttribute("method", call.getMethodName());
xmlWriter.writeAttribute("file", call.getFileName());
xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
xmlWriter.writeCharacters(call.toString());
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
// attempting locks
xmlWriter.writeStartElement("attempting");
for (final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
xmlWriter.writeStartElement("lock");
xmlWriter.writeAttribute("id", attempt.getKey());
for (final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
xmlWriter.writeStartElement("type");
xmlWriter.writeAttribute("id", type.getKey().name());
for (final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
xmlWriter.writeStartElement("mode");
xmlWriter.writeAttribute("id", lockModeOwner.getLockMode().name());
xmlWriter.writeStartElement("thread");
xmlWriter.writeAttribute("id", lockModeOwner.getOwnerThread());
if (lockModeOwner.trace != null && includeStack) {
xmlWriter.writeStartElement("stack-trace");
for (int i = 0; i < lockModeOwner.trace.length; i++) {
xmlWriter.writeStartElement("call");
final StackTraceElement call = lockModeOwner.trace[i];
xmlWriter.writeAttribute("index", Integer.toString(i));
xmlWriter.writeAttribute("class", call.getClassName());
xmlWriter.writeAttribute("method", call.getMethodName());
xmlWriter.writeAttribute("file", call.getFileName());
xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
xmlWriter.writeCharacters(call.toString());
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
}
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
}
use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.
the class LockTableUtils method stateToString.
public static String stateToString(final LockTable lockTable, final boolean includeStack) {
final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
final StringBuilder builder = new StringBuilder();
builder.append(EOL).append("Acquired Locks").append(EOL).append("------------------------------------").append(EOL);
for (final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
builder.append(acquire.getKey()).append(EOL);
for (final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
builder.append('\t').append(type.getKey()).append(EOL);
for (final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
builder.append("\t\t").append(lockModeOwners.getKey()).append('\t');
boolean firstOwner = true;
for (final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
if (!firstOwner) {
builder.append(", ");
} else {
firstOwner = false;
}
final LockCountTraces holdCount = ownerHoldCount.getValue();
builder.append(ownerHoldCount.getKey()).append(" (count=").append(holdCount.count).append(")");
if (holdCount.traces != null && includeStack) {
for (int i = 0; i < holdCount.traces.size(); i++) {
final StackTraceElement[] trace = holdCount.traces.get(i);
builder.append(EOL).append("\t\t\tTrace ").append(i).append(": ").append(EOL);
for (StackTraceElement stackTraceElement : trace) {
builder.append("\t\t\t\t").append(stackTraceElement).append(EOL);
}
}
}
}
builder.append(EOL);
}
}
}
builder.append(EOL).append(EOL);
builder.append("Attempting Locks").append(EOL).append("------------------------------------").append(EOL);
for (final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
builder.append(attempt.getKey()).append(EOL);
for (final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
builder.append('\t').append(type.getKey()).append(EOL);
for (final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
builder.append("\t\t").append(lockModeOwner.getLockMode()).append('\t').append(lockModeOwner.getOwnerThread());
if (lockModeOwner.trace != null && includeStack) {
builder.append(EOL).append("\t\t\tTrace ").append(": ").append(EOL);
for (int i = 0; i < lockModeOwner.trace.length; i++) {
builder.append("\t\t\t\t").append(lockModeOwner.trace[i]).append(EOL);
}
}
builder.append(EOL);
}
}
}
return builder.toString();
}
Aggregations