Use copy on write in repository db

This commit is contained in:
Rene Pfeuffer
2019-12-05 07:57:47 +01:00
parent 9ca2a57667
commit 791437a905
2 changed files with 26 additions and 16 deletions

View File

@@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.ContextEntry;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository;
import sonia.scm.store.CopyOnWrite;
import sonia.scm.store.StoreConstants;
import sonia.scm.update.UpdateStepRepositoryMetadataAccess;
@@ -43,7 +44,10 @@ public class MetadataStore implements UpdateStepRepositoryMetadataAccess<Path> {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(repository, resolveDataPath(path).toFile());
CopyOnWrite.withTemporaryFile(
temp -> marshaller.marshal(repository, temp.toFile()),
resolveDataPath(path)
);
} catch (JAXBException ex) {
throw new InternalRepositoryException(repository, "failed write repository metadata", ex);
}

View File

@@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.ContextEntry;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.store.CopyOnWrite;
import sonia.scm.xml.IndentXMLStreamWriter;
import sonia.scm.xml.XmlStreams;
@@ -40,23 +41,28 @@ class PathDatabase {
ensureParentDirectoryExists();
LOG.trace("write repository path database to {}", storePath);
try (IndentXMLStreamWriter writer = XmlStreams.createWriter(storePath)) {
writer.writeStartDocument(ENCODING, VERSION);
CopyOnWrite.withTemporaryFile(
temp -> {
try (IndentXMLStreamWriter writer = XmlStreams.createWriter(temp)) {
writer.writeStartDocument(ENCODING, VERSION);
writeRepositoriesStart(writer, creationTime, lastModified);
for (Map.Entry<String, Path> e : pathDatabase.entrySet()) {
writeRepository(writer, e.getKey(), e.getValue());
}
writer.writeEndElement();
writeRepositoriesStart(writer, creationTime, lastModified);
for (Map.Entry<String, Path> e : pathDatabase.entrySet()) {
writeRepository(writer, e.getKey(), e.getValue());
}
writer.writeEndElement();
writer.writeEndDocument();
} catch (XMLStreamException | IOException ex) {
throw new InternalRepositoryException(
ContextEntry.ContextBuilder.entity(Path.class, storePath.toString()).build(),
"failed to write repository path database",
ex
);
}
writer.writeEndDocument();
} catch (XMLStreamException | IOException ex) {
throw new InternalRepositoryException(
ContextEntry.ContextBuilder.entity(Path.class, storePath.toString()).build(),
"failed to write repository path database",
ex
);
}
},
storePath
);
}
private void ensureParentDirectoryExists() {