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 org.eclipse.jgit.annotations.NonNull;
|
||||
import org.eclipse.jgit.annotations.Nullable;
|
||||
import org.eclipse.jgit.errors.CorruptObjectException;
|
||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||
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.
|
||||
*/
|
||||
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.reader = reader;
|
||||
if (reader instanceof ObjectReuseAsIs)
|
||||
|
@ -365,7 +384,8 @@ public PackWriter(final PackConfig config, final ObjectReader reader) {
|
|||
deltaBaseAsOffset = config.isDeltaBaseAsOffset();
|
||||
reuseDeltas = config.isReuseDeltas();
|
||||
reuseValidate = true; // be paranoid by default
|
||||
stats = new PackStatistics.Accumulator();
|
||||
stats = statsAccumulator != null ? statsAccumulator
|
||||
: new PackStatistics.Accumulator();
|
||||
state = new MutableState();
|
||||
selfRef = new WeakReference<>(this);
|
||||
instances.put(selfRef, Boolean.TRUE);
|
||||
|
|
|
@ -166,6 +166,36 @@ public long getDeltaBytes() {
|
|||
* POJO for accumulating the statistics.
|
||||
*/
|
||||
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. */
|
||||
public Set<ObjectId> interestingObjects;
|
||||
|
||||
|
@ -270,6 +300,48 @@ public PackStatistics(Accumulator 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.
|
||||
*
|
||||
|
|
|
@ -773,6 +773,7 @@ private void service() throws IOException {
|
|||
boolean sendPack = false;
|
||||
// If it's a non-bidi request, we need to read the entire request before
|
||||
// writing a response. Buffer the response until then.
|
||||
PackStatistics.Accumulator accumulator = new PackStatistics.Accumulator();
|
||||
try {
|
||||
if (biDirectionalPipe)
|
||||
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
|
||||
|
@ -781,12 +782,15 @@ else if (requestValidator instanceof AnyRequestValidator)
|
|||
else
|
||||
advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
|
||||
|
||||
long negotiateStart = System.currentTimeMillis();
|
||||
accumulator.advertised = advertised.size();
|
||||
recvWants();
|
||||
if (wantIds.isEmpty()) {
|
||||
preUploadHook.onBeginNegotiateRound(this, wantIds, 0);
|
||||
preUploadHook.onEndNegotiateRound(this, wantIds, 0, 0, false);
|
||||
return;
|
||||
}
|
||||
accumulator.wants = wantIds.size();
|
||||
|
||||
if (options.contains(OPTION_MULTI_ACK_DETAILED)) {
|
||||
multiAck = MultiAck.DETAILED;
|
||||
|
@ -802,7 +806,10 @@ else if (requestValidator instanceof AnyRequestValidator)
|
|||
processShallow();
|
||||
if (!clientShallowCommits.isEmpty())
|
||||
walk.assumeShallow(clientShallowCommits);
|
||||
sendPack = negotiate();
|
||||
sendPack = negotiate(accumulator);
|
||||
accumulator.timeNegotiating += System.currentTimeMillis()
|
||||
- negotiateStart;
|
||||
|
||||
if (sendPack && !biDirectionalPipe) {
|
||||
// Ensure the request was fully consumed. Any remaining input must
|
||||
// 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)
|
||||
sendPack();
|
||||
sendPack(accumulator);
|
||||
}
|
||||
|
||||
private static Set<ObjectId> refIdSet(Collection<Ref> refs) {
|
||||
|
@ -1093,7 +1100,8 @@ public String getPeerUserAgent() {
|
|||
return UserAgent.getAgent(options, userAgent);
|
||||
}
|
||||
|
||||
private boolean negotiate() throws IOException {
|
||||
private boolean negotiate(PackStatistics.Accumulator accumulator)
|
||||
throws IOException {
|
||||
okToGiveUp = Boolean.FALSE;
|
||||
|
||||
ObjectId last = ObjectId.zeroId();
|
||||
|
@ -1127,7 +1135,7 @@ private boolean negotiate() throws IOException {
|
|||
|
||||
} else if (line.startsWith("have ") && line.length() == 45) { //$NON-NLS-1$
|
||||
peerHas.add(ObjectId.fromString(line.substring(5)));
|
||||
|
||||
accumulator.haves++;
|
||||
} else if (line.equals("done")) { //$NON-NLS-1$
|
||||
last = processHaveLines(peerHas, last);
|
||||
|
||||
|
@ -1485,12 +1493,13 @@ private boolean wantSatisfied(final RevObject want) throws IOException {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void sendPack() throws IOException {
|
||||
private void sendPack(PackStatistics.Accumulator accumulator)
|
||||
throws IOException {
|
||||
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|
||||
|| options.contains(OPTION_SIDE_BAND_64K);
|
||||
if (sideband) {
|
||||
try {
|
||||
sendPack(true);
|
||||
sendPack(true, accumulator);
|
||||
} catch (ServiceMayNotContinueException noPack) {
|
||||
// This was already reported on (below).
|
||||
throw noPack;
|
||||
|
@ -1511,7 +1520,7 @@ private void sendPack() throws IOException {
|
|||
throw err;
|
||||
}
|
||||
} else {
|
||||
sendPack(false);
|
||||
sendPack(false, accumulator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1532,7 +1541,8 @@ private boolean reportInternalServerErrorOverSideband() {
|
|||
}
|
||||
|
||||
@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;
|
||||
OutputStream packOut = rawOut;
|
||||
|
||||
|
@ -1573,7 +1583,8 @@ private void sendPack(final boolean sideband) throws IOException {
|
|||
PackConfig cfg = packConfig;
|
||||
if (cfg == null)
|
||||
cfg = new PackConfig(db);
|
||||
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader());
|
||||
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader(),
|
||||
accumulator);
|
||||
try {
|
||||
pw.setIndexDisabled(true);
|
||||
pw.setUseCachedPacks(true);
|
||||
|
|
Loading…
Reference in New Issue