Add negotiation statistics to PackStatistics
Add fetch statistics for the counts of advertised refs, wants and haves. Also add the duration in milliseconds for the negotiation phase. For non-bidirectional transports like HTTP, this is the time for the final round that sends the pack back to the user. Change-Id: I1af7ffd3cb7b62182340682e2a243691ea24ec2e Signed-off-by: Terry Parker <tparker@google.com>
This commit is contained in:
parent
5efc3dcc6c
commit
302596cc67
|
@ -81,6 +81,7 @@
|
||||||
import java.util.zip.DeflaterOutputStream;
|
import java.util.zip.DeflaterOutputStream;
|
||||||
|
|
||||||
import org.eclipse.jgit.annotations.NonNull;
|
import org.eclipse.jgit.annotations.NonNull;
|
||||||
|
import org.eclipse.jgit.annotations.Nullable;
|
||||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
import org.eclipse.jgit.errors.LargeObjectException;
|
import org.eclipse.jgit.errors.LargeObjectException;
|
||||||
|
@ -355,6 +356,24 @@ public PackWriter(final Repository repo, final ObjectReader reader) {
|
||||||
* reader to read from the repository with.
|
* reader to read from the repository with.
|
||||||
*/
|
*/
|
||||||
public PackWriter(final PackConfig config, final ObjectReader reader) {
|
public PackWriter(final PackConfig config, final ObjectReader reader) {
|
||||||
|
this(config, reader, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create writer with a specified configuration.
|
||||||
|
* <p>
|
||||||
|
* Objects for packing are specified in {@link #preparePack(Iterator)} or
|
||||||
|
* {@link #preparePack(ProgressMonitor, Set, Set)}.
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* configuration for the pack writer.
|
||||||
|
* @param reader
|
||||||
|
* reader to read from the repository with.
|
||||||
|
* @param statsAccumulator
|
||||||
|
* accumulator for statics
|
||||||
|
*/
|
||||||
|
public PackWriter(PackConfig config, final ObjectReader reader,
|
||||||
|
@Nullable PackStatistics.Accumulator statsAccumulator) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
if (reader instanceof ObjectReuseAsIs)
|
if (reader instanceof ObjectReuseAsIs)
|
||||||
|
@ -365,7 +384,8 @@ public PackWriter(final PackConfig config, final ObjectReader reader) {
|
||||||
deltaBaseAsOffset = config.isDeltaBaseAsOffset();
|
deltaBaseAsOffset = config.isDeltaBaseAsOffset();
|
||||||
reuseDeltas = config.isReuseDeltas();
|
reuseDeltas = config.isReuseDeltas();
|
||||||
reuseValidate = true; // be paranoid by default
|
reuseValidate = true; // be paranoid by default
|
||||||
stats = new PackStatistics.Accumulator();
|
stats = statsAccumulator != null ? statsAccumulator
|
||||||
|
: new PackStatistics.Accumulator();
|
||||||
state = new MutableState();
|
state = new MutableState();
|
||||||
selfRef = new WeakReference<>(this);
|
selfRef = new WeakReference<>(this);
|
||||||
instances.put(selfRef, Boolean.TRUE);
|
instances.put(selfRef, Boolean.TRUE);
|
||||||
|
|
|
@ -166,6 +166,36 @@ public long getDeltaBytes() {
|
||||||
* POJO for accumulating the statistics.
|
* POJO for accumulating the statistics.
|
||||||
*/
|
*/
|
||||||
public static class Accumulator {
|
public static class Accumulator {
|
||||||
|
/**
|
||||||
|
* The count of references in the ref advertisement.
|
||||||
|
*
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long advertised;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The count of client wants.
|
||||||
|
*
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long wants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The count of client haves.
|
||||||
|
*
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long haves;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time in ms spent in the negotiation phase. For non-bidirectional
|
||||||
|
* transports (e.g., HTTP), this is only for the final request that
|
||||||
|
* sends back the pack file.
|
||||||
|
*
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long timeNegotiating;
|
||||||
|
|
||||||
/** The set of objects to be included in the pack. */
|
/** The set of objects to be included in the pack. */
|
||||||
public Set<ObjectId> interestingObjects;
|
public Set<ObjectId> interestingObjects;
|
||||||
|
|
||||||
|
@ -270,6 +300,48 @@ public PackStatistics(Accumulator accumulator) {
|
||||||
statistics = accumulator;
|
statistics = accumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of references in the ref advertisement.
|
||||||
|
*
|
||||||
|
* @return count of refs in the ref advertisement.
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long getAdvertised() {
|
||||||
|
return statistics.advertised;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of client wants.
|
||||||
|
*
|
||||||
|
* @return count of client wants.
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long getWants() {
|
||||||
|
return statistics.wants;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the count of client haves.
|
||||||
|
*
|
||||||
|
* @return count of client haves.
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long getHaves() {
|
||||||
|
return statistics.haves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time in ms spent in the negotiation phase. For non-bidirectional
|
||||||
|
* transports (e.g., HTTP), this is only for the final request that sends
|
||||||
|
* back the pack file.
|
||||||
|
*
|
||||||
|
* @return time for ref advertisement in ms.
|
||||||
|
* @since 4.11
|
||||||
|
*/
|
||||||
|
public long getTimeNegotiating() {
|
||||||
|
return statistics.timeNegotiating;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get unmodifiable collection of objects to be included in the pack.
|
* Get unmodifiable collection of objects to be included in the pack.
|
||||||
*
|
*
|
||||||
|
|
|
@ -773,6 +773,7 @@ private void service() throws IOException {
|
||||||
boolean sendPack = false;
|
boolean sendPack = false;
|
||||||
// If it's a non-bidi request, we need to read the entire request before
|
// If it's a non-bidi request, we need to read the entire request before
|
||||||
// writing a response. Buffer the response until then.
|
// writing a response. Buffer the response until then.
|
||||||
|
PackStatistics.Accumulator accumulator = new PackStatistics.Accumulator();
|
||||||
try {
|
try {
|
||||||
if (biDirectionalPipe)
|
if (biDirectionalPipe)
|
||||||
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
|
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
|
||||||
|
@ -781,12 +782,15 @@ else if (requestValidator instanceof AnyRequestValidator)
|
||||||
else
|
else
|
||||||
advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
|
advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
|
||||||
|
|
||||||
|
long negotiateStart = System.currentTimeMillis();
|
||||||
|
accumulator.advertised = advertised.size();
|
||||||
recvWants();
|
recvWants();
|
||||||
if (wantIds.isEmpty()) {
|
if (wantIds.isEmpty()) {
|
||||||
preUploadHook.onBeginNegotiateRound(this, wantIds, 0);
|
preUploadHook.onBeginNegotiateRound(this, wantIds, 0);
|
||||||
preUploadHook.onEndNegotiateRound(this, wantIds, 0, 0, false);
|
preUploadHook.onEndNegotiateRound(this, wantIds, 0, 0, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
accumulator.wants = wantIds.size();
|
||||||
|
|
||||||
if (options.contains(OPTION_MULTI_ACK_DETAILED)) {
|
if (options.contains(OPTION_MULTI_ACK_DETAILED)) {
|
||||||
multiAck = MultiAck.DETAILED;
|
multiAck = MultiAck.DETAILED;
|
||||||
|
@ -802,7 +806,10 @@ else if (requestValidator instanceof AnyRequestValidator)
|
||||||
processShallow();
|
processShallow();
|
||||||
if (!clientShallowCommits.isEmpty())
|
if (!clientShallowCommits.isEmpty())
|
||||||
walk.assumeShallow(clientShallowCommits);
|
walk.assumeShallow(clientShallowCommits);
|
||||||
sendPack = negotiate();
|
sendPack = negotiate(accumulator);
|
||||||
|
accumulator.timeNegotiating += System.currentTimeMillis()
|
||||||
|
- negotiateStart;
|
||||||
|
|
||||||
if (sendPack && !biDirectionalPipe) {
|
if (sendPack && !biDirectionalPipe) {
|
||||||
// Ensure the request was fully consumed. Any remaining input must
|
// Ensure the request was fully consumed. Any remaining input must
|
||||||
// be a protocol error. If we aren't at EOF the implementation is broken.
|
// be a protocol error. If we aren't at EOF the implementation is broken.
|
||||||
|
@ -849,7 +856,7 @@ else if (requestValidator instanceof AnyRequestValidator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendPack)
|
if (sendPack)
|
||||||
sendPack();
|
sendPack(accumulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<ObjectId> refIdSet(Collection<Ref> refs) {
|
private static Set<ObjectId> refIdSet(Collection<Ref> refs) {
|
||||||
|
@ -1093,7 +1100,8 @@ public String getPeerUserAgent() {
|
||||||
return UserAgent.getAgent(options, userAgent);
|
return UserAgent.getAgent(options, userAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean negotiate() throws IOException {
|
private boolean negotiate(PackStatistics.Accumulator accumulator)
|
||||||
|
throws IOException {
|
||||||
okToGiveUp = Boolean.FALSE;
|
okToGiveUp = Boolean.FALSE;
|
||||||
|
|
||||||
ObjectId last = ObjectId.zeroId();
|
ObjectId last = ObjectId.zeroId();
|
||||||
|
@ -1127,7 +1135,7 @@ private boolean negotiate() throws IOException {
|
||||||
|
|
||||||
} else if (line.startsWith("have ") && line.length() == 45) { //$NON-NLS-1$
|
} else if (line.startsWith("have ") && line.length() == 45) { //$NON-NLS-1$
|
||||||
peerHas.add(ObjectId.fromString(line.substring(5)));
|
peerHas.add(ObjectId.fromString(line.substring(5)));
|
||||||
|
accumulator.haves++;
|
||||||
} else if (line.equals("done")) { //$NON-NLS-1$
|
} else if (line.equals("done")) { //$NON-NLS-1$
|
||||||
last = processHaveLines(peerHas, last);
|
last = processHaveLines(peerHas, last);
|
||||||
|
|
||||||
|
@ -1485,12 +1493,13 @@ private boolean wantSatisfied(final RevObject want) throws IOException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendPack() throws IOException {
|
private void sendPack(PackStatistics.Accumulator accumulator)
|
||||||
|
throws IOException {
|
||||||
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|
||||||
|| options.contains(OPTION_SIDE_BAND_64K);
|
|| options.contains(OPTION_SIDE_BAND_64K);
|
||||||
if (sideband) {
|
if (sideband) {
|
||||||
try {
|
try {
|
||||||
sendPack(true);
|
sendPack(true, accumulator);
|
||||||
} catch (ServiceMayNotContinueException noPack) {
|
} catch (ServiceMayNotContinueException noPack) {
|
||||||
// This was already reported on (below).
|
// This was already reported on (below).
|
||||||
throw noPack;
|
throw noPack;
|
||||||
|
@ -1511,7 +1520,7 @@ private void sendPack() throws IOException {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendPack(false);
|
sendPack(false, accumulator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1532,7 +1541,8 @@ private boolean reportInternalServerErrorOverSideband() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void sendPack(final boolean sideband) throws IOException {
|
private void sendPack(final boolean sideband,
|
||||||
|
PackStatistics.Accumulator accumulator) throws IOException {
|
||||||
ProgressMonitor pm = NullProgressMonitor.INSTANCE;
|
ProgressMonitor pm = NullProgressMonitor.INSTANCE;
|
||||||
OutputStream packOut = rawOut;
|
OutputStream packOut = rawOut;
|
||||||
|
|
||||||
|
@ -1573,7 +1583,8 @@ private void sendPack(final boolean sideband) throws IOException {
|
||||||
PackConfig cfg = packConfig;
|
PackConfig cfg = packConfig;
|
||||||
if (cfg == null)
|
if (cfg == null)
|
||||||
cfg = new PackConfig(db);
|
cfg = new PackConfig(db);
|
||||||
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader());
|
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader(),
|
||||||
|
accumulator);
|
||||||
try {
|
try {
|
||||||
pw.setIndexDisabled(true);
|
pw.setIndexDisabled(true);
|
||||||
pw.setUseCachedPacks(true);
|
pw.setUseCachedPacks(true);
|
||||||
|
|
Loading…
Reference in New Issue