diff --git a/lib/retrieval-stats.js b/lib/retrieval-stats.js index 3db4e8a9..ef2d4d37 100644 --- a/lib/retrieval-stats.js +++ b/lib/retrieval-stats.js @@ -58,6 +58,7 @@ export const buildRetrievalStats = (measurements, telemetryPoint) => { const ttfbValues = [] const durationValues = [] const sizeValues = [] + let httpSuccesses = 0 for (const m of measurements) { // `retrievalResult` should be always set by lib/preprocess.js, so we should never encounter @@ -99,11 +100,15 @@ export const buildRetrievalStats = (measurements, telemetryPoint) => { const taskId = getTaskId(m) if (m.indexerResult) tasksWithIndexerResults.add(taskId) if (m.indexerResult === 'OK') tasksWithHttpAdvertisement.add(taskId) + + // A successful HTTP response is a response with result breakdown set to OK and the protocol being used is set to HTTP. + if (m.retrievalResult === 'OK' && m.protocol.toLowerCase() === 'http') { httpSuccesses++ } } const successRate = resultBreakdown.OK / totalCount - + const successRateHttp = httpSuccesses / totalCount telemetryPoint.intField('unique_tasks', uniqueTasksCount) telemetryPoint.floatField('success_rate', successRate) + telemetryPoint.floatField('success_rate_http', successRateHttp) telemetryPoint.intField('participants', participants.size) telemetryPoint.intField('inet_groups', inetGroups.size) telemetryPoint.intField('measurements', totalCount) diff --git a/test/evaluate.js b/test/evaluate.js index 52825a7d..2e01baee 100644 --- a/test/evaluate.js +++ b/test/evaluate.js @@ -322,6 +322,8 @@ describe('evaluate', async function () { assertPointFieldValue(point, 'measurements', '1i') assertPointFieldValue(point, 'unique_tasks', '1i') assertPointFieldValue(point, 'success_rate', '1') + // The default protocol is not http. While the overall success rate is 1, we expect the http success rate to be 0. + assertPointFieldValue(point, 'success_rate_http', '0') point = telemetry.find(p => p.name === 'retrieval_stats_all') assert(!!point, @@ -329,6 +331,7 @@ describe('evaluate', async function () { assertPointFieldValue(point, 'measurements', '10i') assertPointFieldValue(point, 'unique_tasks', '2i') assertPointFieldValue(point, 'success_rate', '0.5') + assertPointFieldValue(point, 'success_rate_http', '0') }) it('prepares provider retrieval result stats', async () => { diff --git a/test/retrieval-stats.test.js b/test/retrieval-stats.test.js index 20d5c60a..813ed856 100644 --- a/test/retrieval-stats.test.js +++ b/test/retrieval-stats.test.js @@ -208,6 +208,41 @@ describe('retrieval statistics', () => { assertPointFieldValue(point, 'nano_score_per_inet_group_p50', '333333333i' /* =2/6 */) assertPointFieldValue(point, 'nano_score_per_inet_group_max', '500000000i' /* =3/6 */) }) + + it('records successful http rate', async () => { + /** @type {Measurement[]} */ + const measurements = [ + { + // Standard measurement, no http protocol used + ...VALID_MEASUREMENT, + protocol: 'graphsync' + }, + { + // A successful http measurement + ...VALID_MEASUREMENT, + protocol: 'http' + }, + { + ...VALID_MEASUREMENT, + protocol: 'http', + retrievalResult: 'HTTP_500' + }, + { + ...VALID_MEASUREMENT, + // Should not be picked up, as the retrieval timed out + retrievalResult: 'TIMEOUT', + protocol: 'http' + } + ] + + const point = new Point('stats') + buildRetrievalStats(measurements, point) + debug('stats', point.fields) + + assertPointFieldValue(point, 'success_rate', '0.5') + // Only one of the successful measurements used http + assertPointFieldValue(point, 'success_rate_http', '0.25') + }) }) describe('getValueAtPercentile', () => {