Skip to content

Commit

Permalink
Track whether media are served from the cache. (#27562)
Browse files Browse the repository at this point in the history
  • Loading branch information
gmajoulet committed Apr 6, 2020
1 parent ab0ec42 commit 1b0d4cd
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 9 deletions.
31 changes: 30 additions & 1 deletion extensions/amp-story/1.0/media-performance-metrics-service.js
Expand Up @@ -20,9 +20,11 @@ import {
} from '../../../src/event-helper';
import {Services} from '../../../src/services';
import {dev} from '../../../src/log';
import {escapeCssSelectorIdent} from '../../../src/css';
import {lastChildElement} from '../../../src/dom';
import {map} from '../../../src/utils/object';
import {registerServiceBuilder} from '../../../src/service';
import {urls} from '../../../src/config';

/**
* Media status.
Expand All @@ -35,6 +37,16 @@ const Status = {
WAITING: 3,
};

/**
* Cache serving status.
* @enum
*/
const CacheState = {
ORIGIN: 0, // Served from origin.
ORIGIN_CACHE_MISS: 1, // Served from origin even though cache URL was present.
CACHE: 2, // Served from cache.
};

/**
* @typedef {{
* start: number,
Expand Down Expand Up @@ -116,6 +128,9 @@ export class MediaPerformanceMetricsService {

/** @private @const {!../../../src/service/performance-impl.Performance} */
this.performanceService_ = Services.performanceFor(win);

/** @private @const {!../../../src/service/url-impl.Url} */
this.urlService_ = Services.urlForDoc(win.document.body);
}

/**
Expand Down Expand Up @@ -192,7 +207,21 @@ export class MediaPerformanceMetricsService {
* @private
*/
sendMetrics_(mediaEntry) {
const {metrics} = mediaEntry;
const {media, metrics} = mediaEntry;

let videoCacheState;
if (this.urlService_.isProxyOrigin(media.currentSrc)) {
videoCacheState = CacheState.CACHE;
} else {
// Media is served from origin. Checks if there was a cached source.
const {hostname} = this.urlService_.parse(urls.cdn);
videoCacheState = media.querySelector(
`[src*="${escapeCssSelectorIdent(hostname)}"]`
)
? CacheState.ORIGIN_CACHE_MISS
: CacheState.ORIGIN;
}
this.performanceService_.tickDelta('vcs', videoCacheState);

// If the media errored.
if (metrics.error !== null) {
Expand Down
Expand Up @@ -19,7 +19,7 @@ import {MEDIA_LOAD_FAILURE_SRC_PROPERTY} from '../../../../src/event-helper';
import {MediaPerformanceMetricsService} from '../media-performance-metrics-service';
import {Services} from '../../../../src/services';

describes.fakeWin('media-performance-metrics-service', {}, (env) => {
describes.fakeWin('media-performance-metrics-service', {amp: true}, (env) => {
let clock;
let service;
let tickStub;
Expand All @@ -42,7 +42,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
env.sandbox
.stub(Services, 'performanceFor')
.returns({tickDelta: () => {}, flush: () => {}});
service = new MediaPerformanceMetricsService();
service = new MediaPerformanceMetricsService(win);
tickStub = env.sandbox.stub(service.performanceService_, 'tickDelta');
});

Expand All @@ -62,7 +62,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
clock.tick(300);
service.stopMeasuring(video);

expect(tickStub).to.have.callCount(5);
expect(tickStub).to.have.callCount(6);
expect(flushStub).to.have.been.calledOnce;
});

Expand All @@ -76,7 +76,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
clock.tick(10000);
service.stopMeasuring(video);

expect(tickStub).to.have.callCount(1);
expect(tickStub).to.have.callCount(2);
expect(flushStub).to.have.been.calledOnce;
});

Expand All @@ -96,7 +96,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
video2.dispatchEvent(new Event('playing'));
service.stopMeasuring(video2);

expect(tickStub).to.have.callCount(9);
expect(tickStub).to.have.callCount(11);
expect(flushStub).to.have.been.calledTwice;
});

Expand Down Expand Up @@ -345,7 +345,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
service.startMeasuring(video);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledOnceWithExactly('verr', 4);
expect(tickStub).to.have.been.calledWithExactly('verr', 4);
done();
};

Expand All @@ -360,7 +360,7 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
service.startMeasuring(video);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledOnceWithExactly('verr', 0);
expect(tickStub).to.have.been.calledWithExactly('verr', 0);
});

it('should detect that the video errors', () => {
Expand All @@ -373,7 +373,55 @@ describes.fakeWin('media-performance-metrics-service', {}, (env) => {
clock.tick(300);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledOnceWithExactly('verr', 0);
expect(tickStub).to.have.been.calledWithExactly('verr', 0);
});
});

describe('Cache state', () => {
it('should register the video as playing from origin', () => {
const video = win.document.createElement('video');
const source = win.document.createElement('source');
source.setAttribute('src', 'foo.mp4');
video.appendChild(source);
env.sandbox.stub(video, 'currentSrc').value('foo.mp4');

service.startMeasuring(video);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledWithExactly('vcs', 0);
});

it('should register the video as playing from origin w/ cache miss', () => {
const video = win.document.createElement('video');
const cacheSource = win.document.createElement('source');
const originSource = win.document.createElement('source');
cacheSource.setAttribute(
'src',
'htps://foo-com.cdn.ampproject.org/bv/s/foo.com/foo.mp4'
);
originSource.setAttribute('src', 'foo.mp4');
video.appendChild(cacheSource);
video.appendChild(originSource);
env.sandbox.stub(video, 'currentSrc').value('foo.mp4');

service.startMeasuring(video);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledWithExactly('vcs', 1);
});

it('should register the video as playing from cache', () => {
const url = 'https://foo-com.cdn.ampproject.org/bv/s/foo.com/foo.mp4';
const video = win.document.createElement('video');
const source = win.document.createElement('source');
source.setAttribute('src', url);
video.appendChild(source);
env.sandbox.stub(video, 'currentSrc').value(url);

service.startMeasuring(video);
service.stopMeasuring(video);

expect(tickStub).to.have.been.calledWithExactly('vcs', 2);
});
});
});

0 comments on commit 1b0d4cd

Please sign in to comment.