Commit 6d639f1b authored by Jonathan Haas's avatar Jonathan Haas

Merge branch 'bugfix/filehandles' into 'develop'

Fehlerkorrektur "Too many open files"

See merge request ERZ/SWE_de.bsvrz.ars.ars!14
parents 42cd12cf d6a35420
......@@ -19,6 +19,12 @@
- [Fehler 8](https://gitlab.nerz-ev.de/ERZ/SWE_de.bsvrz.ars.ars/issues/8): Eine Archivinformationsanfrage mit einem Anfragebereich, in dem keine Daten ermittelbar sind, resultierte in einem Ergebnis von Zeitstempel -1 bis -1 (1.1.1970 bis 1.1.1970) und Markierung "Keine Lücke". Dieser Datensatz wird nun nicht mehr gesendet.
- Die minütlichen Debug-Ausgaben über die Queue-Größen und Anzahl empfangener Datensätze werden nun wieder (wie bei Version 3.x) am Anfang jeder Minute publiziert, statt willkürlich ungefähr alle 60 Sekunden. Da viele Verkehrswerte ebenfalls minütlich erzeugt werden, ist dadurch eine bessere Vergleichbarkeit der Werte gegeben.
- Bei der Migration von verkürzten Containerdateien in die neue `_deleted.dat`-Datei (siehe Update-Hinweise zu 4.0.0 Beta) wurde ein Datei-Handle nach Benutzung nicht korrekt geschlossen, was zu "Too many open files"-Fehlern führen konnte.
- Der Nachfordern-Task blockiert, während er läuft, jetzt keine gleichzeitigen lesenden Zugriffe auf die Containerdateien mehr, sodass sich Archivanfragen und Nachforderungen nicht mehr gegenseitig behindern.
- Tippfehlerkorrektur in Debug-Ausgaben.
## [Version 4.2.0 Beta]
......
......@@ -1689,7 +1689,7 @@ public final class InQueuesMgr {
for(final ResultData rd : rds) {
// *** NUR FÜR TESTZWECKE
if(ArchiveManager.DATAINDEX_OFFSET != 0) {
logger.warning("Datenindex-Offest aktiviert! (" + ArchiveManager.DATAINDEX_OFFSET + ")");
logger.warning("Datenindex-Offset aktiviert! (" + ArchiveManager.DATAINDEX_OFFSET + ")");
try {
JavaSpy.setFieldValue(rd, "dataIndex", rd.getDataIndex() + ArchiveManager.DATAINDEX_OFFSET);
}
......
......@@ -468,10 +468,6 @@ public class RequestGapTask extends SingleClientSenderTask {
try {
suspendTaskIfNecessary(); //Hält den Task an, falls das Archivsystem im kritischen Bereich.
if(!din.arSParamIsNachfordern()) {
_debug.fine("Nachfordern ist nicht parametriert für " + din.getDataIdentification() + ".");
return; // Nachfordern nicht parametriert
......@@ -496,64 +492,56 @@ public class RequestGapTask extends SingleClientSenderTask {
return;
}
// Synchronisierung über DataIdentNode (Busy-Area):
try(DinLock lock = din.lockContainers()) {
if(lock == null) {
_debug.warning("Nachfordern fehlgeschlagen fuer Datenidentifikation: " + din);
return;
}
dataDesc = new DataDescription(archMgr.getAtg(atg), archMgr.getAsp(asp));
object = archMgr.getObj(obj);
dataDesc = new DataDescription(archMgr.getAtg(atg), archMgr.getAsp(asp));
object = archMgr.getObj(obj);
final IdDataIdentification dataIdentification = new IdDataIdentification(obj, atg, asp, sv);
QueryDataSequence dataSequence = new QueryDataSequence(archMgr, archMgr.getDataIdentTree().existsCreate(dataIdentification), ArchiveDataKindCombination
.all(), ats, ArchiveOrder.BY_INDEX, DeletedTreatment.Full);
final IdDataIdentification dataIdentification = new IdDataIdentification(obj, atg, asp, sv);
QueryDataSequence dataSequence = new QueryDataSequence(archMgr, archMgr.getDataIdentTree().existsCreate(dataIdentification), ArchiveDataKindCombination
.all(), ats, ArchiveOrder.BY_INDEX, DeletedTreatment.Full);
boolean skipLine = false;
try(DataIterator iterator = dataSequence.iterator()) {
boolean skipLine = false;
try(DataIterator iterator = dataSequence.iterator()) {
long lowDidx = -1, lowDTime = -1, lowATime = -1;
long lowDidx = -1, lowDTime = -1, lowATime = -1;
gapFile = new GapFile(obj, atg, asp, sv);
gapFile.createTmpGapFile();
boolean startCondition = false;
while(!iterator.isEmpty()) {
gapFile = new GapFile(obj, atg, asp, sv);
gapFile.createTmpGapFile();
boolean startCondition = false;
while(!iterator.isEmpty()) {
if(shouldTerminate()) break;
if(shouldTerminate()) break;
long hiDidx = iterator.peekDataIndex();
long hiDidx = iterator.peekDataIndex();
// Prüfen, ob wir im angegebenen Bereich sind. Dies ist der Fall, wenn die Lücke
// vollständig im Bereich liegt. Ggf. Lückendatei vor und nach dem Bereich kopieren.
if(!startCondition) {
if(startCondition(ats, lowDidx, lowDTime, lowATime)) {
gapFile.copyGapsUpToHere(lowDidx);
startCondition = true;
}
// Prüfen, ob wir im angegebenen Bereich sind. Dies ist der Fall, wenn die Lücke
// vollständig im Bereich liegt. Ggf. Lückendatei vor und nach dem Bereich kopieren.
if(!startCondition) {
if(startCondition(ats, lowDidx, lowDTime, lowATime)) {
gapFile.copyGapsUpToHere(lowDidx);
startCondition = true;
}
if(startCondition) {
if(isGap(lowDidx, hiDidx)) {
totalGapsFound.incrementAndGet();
newGaps.reset();
// rausfinden, wo wir fragen müssen, wo erfolglos gefragt wurde und wo von den erfolglosen
// wir nicht mehr fragen (weil die auch weiterhin in der Lückendatei vermerkt sein sollen):
String[] failedArchives = gapFile.getEntry(lowDidx, hiDidx);
String[] unaskedArchives = extractUnaskedArS(requestArchives, failedArchives);
skipLine = failedArchives.length > 0; // wenn es einen Eintrag gab, diesen beim Kopieren überspringen
requestGap(requestArchives, 0, lowDidx, hiDidx, unaskedArchives, gapFile, newGaps);
gapFile.appendToTmpGapFile(newGaps.reduce());
}
}
if(startCondition) {
if(isGap(lowDidx, hiDidx)) {
totalGapsFound.incrementAndGet();
newGaps.reset();
// rausfinden, wo wir fragen müssen, wo erfolglos gefragt wurde und wo von den erfolglosen
// wir nicht mehr fragen (weil die auch weiterhin in der Lückendatei vermerkt sein sollen):
String[] failedArchives = gapFile.getEntry(lowDidx, hiDidx);
String[] unaskedArchives = extractUnaskedArS(requestArchives, failedArchives);
skipLine = failedArchives.length > 0; // wenn es einen Eintrag gab, diesen beim Kopieren überspringen
requestGap(requestArchives, 0, lowDidx, hiDidx, unaskedArchives, gapFile, newGaps);
gapFile.appendToTmpGapFile(newGaps.reduce());
}
lowDidx = hiDidx;
lowDTime = iterator.peekDataTime();
lowATime = iterator.peekArchiveTime();
iterator.remove();
}
lowDidx = hiDidx;
lowDTime = iterator.peekDataTime();
lowATime = iterator.peekArchiveTime();
iterator.remove();
}
gapFile.copyRestGaps(skipLine);
}
gapFile.copyRestGaps(skipLine);
}
catch(InterruptedException e) {
_debug.fine("Nachfordern wurde unterbrochen: '" + Util.did2Str(obj, atg, asp, sv) + "': " + e.getMessage());
......
......@@ -55,8 +55,7 @@ public class DeletedContainerDataIterator implements DataIterator {
public DeletedContainerDataIterator(final BasicContainerFileHandle containerFileHandle) throws PersistenceException {
_containerFileHandle = containerFileHandle;
try {
BufferedRandomAccessFile file = new BufferedRandomAccessFile(containerFileHandle.getFile());
try (BufferedRandomAccessFile file = new BufferedRandomAccessFile(containerFileHandle.getFile())) {
skipContainerHeader(file);
_listOfIndexesDeleted = getListOfIndexesDeleted(file);
}
......
......@@ -160,9 +160,9 @@ public class AbstractIndex<E extends Enum<E>> implements AutoCloseable {
}
/**
* Ermittelt alle Index-Zeilen, die zu der angegebenen Anfrage passen. Das Ergebnis wird Performant ermittelt, indem
* alle bekannten Einschränkungen ausgewertet werden. Wird nach Daten eingeschränkt, die nicht im Index vorkommen,
* dann werden ggf. überflüssige Zeilen/Container usw. zurückgegeben. Hier muss dann der Anfrager entsprechnd selbst filtern.
* Ermittelt alle Index-Zeilen, die zu der angegebenen Anfrage passen. Das Ergebnis wird performant ermittelt, indem
* alle bekannten Einschränkungen ausgewertet werden. Wird nach Spalten eingeschränkt, die nicht im Index vorkommen,
* dann werden ggf. überflüssige Zeilen/Container usw. zurückgegeben. Hier muss dann der Anfrager entsprechend selbst filtern.
*
* @param query Anfrage. Zu jeder Spalte in dem Index kann ein von/bis-Bereich angegeben werden, zu dem Container geliefert werden sollen.
* Wie für Archivdaten üblich, wird als erster Container ggf. der Container zurückgegeben, der den letzten Datensatz vor dem Anfragezeitraum
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment