Browse Source

Merge branch 'stable-4.6'

* stable-4.6:
  Don't remove pack when FileNotFoundException is transient

Change-Id: I82941a98385cda27c89e1e6750b7b6db4e39f414
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
stable-4.7
Matthias Sohn 8 years ago
parent
commit
dab8e0e7cb
  1. 4
      org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
  2. 34
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
  3. 11
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java

4
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties

@ -271,7 +271,7 @@ exceptionCaughtDuringExcecutionOfCommand=Exception caught during execution of co
exceptionHookExecutionInterrupted=Execution of "{0}" hook interrupted. exceptionHookExecutionInterrupted=Execution of "{0}" hook interrupted.
exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command
exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1} exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1}
exceptionWhileReadingPack=ERROR: Exception caught while accessing pack file {0}, the pack file might be corrupt exceptionWhileReadingPack=ERROR: Exception caught while accessing pack file {0}, the pack file might be corrupt, {1}. Caught {2} consecutive errors while trying to read this pack.
expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
expectedACKNAKGot=Expected ACK/NAK, got: {0} expectedACKNAKGot=Expected ACK/NAK, got: {0}
expectedBooleanStringValue=Expected boolean string value expectedBooleanStringValue=Expected boolean string value
@ -475,7 +475,7 @@ packfileIsTruncated=Packfile {0} is truncated.
packfileIsTruncatedNoParam=Packfile is truncated. packfileIsTruncatedNoParam=Packfile is truncated.
packHandleIsStale=Pack file {0} handle is stale, removing it from pack list packHandleIsStale=Pack file {0} handle is stale, removing it from pack list
packHasUnresolvedDeltas=pack has unresolved deltas packHasUnresolvedDeltas=pack has unresolved deltas
packInaccessible=Pack file {0} now inaccessible; removing it from pack list packInaccessible=Failed to access pack file {0}, caught {2} consecutive errors while trying to access this pack.
packingCancelledDuringObjectsWriting=Packing cancelled during objects writing packingCancelledDuringObjectsWriting=Packing cancelled during objects writing
packObjectCountMismatch=Pack object count mismatch: pack {0} index {1}: {2} packObjectCountMismatch=Pack object count mismatch: pack {0} index {1}: {2}
packRefs=Pack refs packRefs=Pack refs

34
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java

@ -349,6 +349,7 @@ public class ObjectDirectory extends FileObjectDatabase {
for (PackFile p : pList.packs) { for (PackFile p : pList.packs) {
try { try {
p.resolve(matches, id, RESOLVE_ABBREV_LIMIT); p.resolve(matches, id, RESOLVE_ABBREV_LIMIT);
p.resetTransientErrorCount();
} catch (IOException e) { } catch (IOException e) {
handlePackError(e, p); handlePackError(e, p);
} }
@ -430,6 +431,7 @@ public class ObjectDirectory extends FileObjectDatabase {
for (PackFile p : pList.packs) { for (PackFile p : pList.packs) {
try { try {
ObjectLoader ldr = p.get(curs, objectId); ObjectLoader ldr = p.get(curs, objectId);
p.resetTransientErrorCount();
if (ldr != null) if (ldr != null)
return ldr; return ldr;
} catch (PackMismatchException e) { } catch (PackMismatchException e) {
@ -510,6 +512,7 @@ public class ObjectDirectory extends FileObjectDatabase {
for (PackFile p : pList.packs) { for (PackFile p : pList.packs) {
try { try {
long len = p.getObjectSize(curs, id); long len = p.getObjectSize(curs, id);
p.resetTransientErrorCount();
if (0 <= len) if (0 <= len)
return len; return len;
} catch (PackMismatchException e) { } catch (PackMismatchException e) {
@ -549,6 +552,7 @@ public class ObjectDirectory extends FileObjectDatabase {
for (final PackFile p : pList.packs) { for (final PackFile p : pList.packs) {
try { try {
LocalObjectRepresentation rep = p.representation(curs, otp); LocalObjectRepresentation rep = p.representation(curs, otp);
p.resetTransientErrorCount();
if (rep != null) if (rep != null)
packer.select(otp, rep); packer.select(otp, rep);
} catch (PackMismatchException e) { } catch (PackMismatchException e) {
@ -569,6 +573,8 @@ public class ObjectDirectory extends FileObjectDatabase {
private void handlePackError(IOException e, PackFile p) { private void handlePackError(IOException e, PackFile p) {
String warnTmpl = null; String warnTmpl = null;
int transientErrorCount = 0;
String errTmpl = JGitText.get().exceptionWhileReadingPack;
if ((e instanceof CorruptObjectException) if ((e instanceof CorruptObjectException)
|| (e instanceof PackInvalidException)) { || (e instanceof PackInvalidException)) {
warnTmpl = JGitText.get().corruptPack; warnTmpl = JGitText.get().corruptPack;
@ -576,14 +582,17 @@ public class ObjectDirectory extends FileObjectDatabase {
removePack(p); removePack(p);
} else if (e instanceof FileNotFoundException) { } else if (e instanceof FileNotFoundException) {
if (p.getPackFile().exists()) { if (p.getPackFile().exists()) {
warnTmpl = JGitText.get().packInaccessible; errTmpl = JGitText.get().packInaccessible;
transientErrorCount = p.incrementTransientErrorCount();
} else { } else {
warnTmpl = JGitText.get().packWasDeleted; warnTmpl = JGitText.get().packWasDeleted;
removePack(p);
} }
removePack(p);
} else if (FileUtils.isStaleFileHandleInCausalChain(e)) { } else if (FileUtils.isStaleFileHandleInCausalChain(e)) {
warnTmpl = JGitText.get().packHandleIsStale; warnTmpl = JGitText.get().packHandleIsStale;
removePack(p); removePack(p);
} else {
transientErrorCount = p.incrementTransientErrorCount();
} }
if (warnTmpl != null) { if (warnTmpl != null) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@ -594,14 +603,25 @@ public class ObjectDirectory extends FileObjectDatabase {
p.getPackFile().getAbsolutePath())); p.getPackFile().getAbsolutePath()));
} }
} else { } else {
// Don't remove the pack from the list, as the error may be if (doLogExponentialBackoff(transientErrorCount)) {
// transient. // Don't remove the pack from the list, as the error may be
LOG.error(MessageFormat.format( // transient.
JGitText.get().exceptionWhileReadingPack, p.getPackFile() LOG.error(MessageFormat.format(errTmpl,
.getAbsolutePath()), e); p.getPackFile().getAbsolutePath()),
Integer.valueOf(transientErrorCount), e);
}
} }
} }
/**
* @param n
* count of consecutive failures
* @return @{code true} if i is a power of 2
*/
private boolean doLogExponentialBackoff(int n) {
return (n & (n - 1)) == 0;
}
@Override @Override
InsertLooseObjectResult insertUnpackedObject(File tmp, ObjectId id, InsertLooseObjectResult insertUnpackedObject(File tmp, ObjectId id,
boolean createDuplicate) throws IOException { boolean createDuplicate) throws IOException {

11
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java

@ -62,6 +62,7 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -127,6 +128,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
private boolean invalidBitmap; private boolean invalidBitmap;
private AtomicInteger transientErrorCount = new AtomicInteger();
private byte[] packChecksum; private byte[] packChecksum;
private PackIndex loadedIdx; private PackIndex loadedIdx;
@ -571,6 +574,14 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
invalid = true; invalid = true;
} }
int incrementTransientErrorCount() {
return transientErrorCount.incrementAndGet();
}
void resetTransientErrorCount() {
transientErrorCount.set(0);
}
private void readFully(final long position, final byte[] dstbuf, private void readFully(final long position, final byte[] dstbuf,
int dstoff, final int cnt, final WindowCursor curs) int dstoff, final int cnt, final WindowCursor curs)
throws IOException { throws IOException {

Loading…
Cancel
Save