Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/build-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { assign } from './ponyfills/objects.js';
* @property {string} [endpoint]
* @property {boolean} [autoConfirm]
* @property {RequestHooks} [hooks]
* @property {boolean} [analytics]
* @property {*} [store]
* @property {*} [context]
* @property {*} [auth]
Expand Down Expand Up @@ -44,7 +43,6 @@ export function buildOptions(options) {

opts.version = opts.version || 1;
opts.endpoint = ((opts.endpoint && opts.endpoint.replace(/\/$/, '')) || 'https://participants.evolv.ai') + '/v' + opts.version;
opts.analytics = 'analytics' in opts ? opts.analytics : opts.version > 1;

opts.hooks = assign({}, opts.hooks);

Expand Down
99 changes: 26 additions & 73 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ function EvolvClient(opts) {
clientName: options.clientName
};

const contextBeacon = options.analytics ? new Beacon(options.endpoint + '/' + options.environment + '/data', context, beaconOptions) : null;
const eventBeacon = options.beacon || new Beacon(options.endpoint + '/' + options.environment + '/events', context, beaconOptions);
Comment on lines -56 to -57

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was the idea that event beacon would be used if analytics was turned off, but now we only use analytics so it'll always be made?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contextBeacon came in after eventBeacon. eventBeacon gave all the info for visitor based tests. Session based were new and were set to be optional. Now all tests are session based

const contextBeacon = new Beacon(options.endpoint + '/' + options.environment + '/data', context, beaconOptions);

/**
* The context against which the key predicates will be evaluated.
Expand Down Expand Up @@ -214,29 +213,12 @@ function EvolvClient(opts) {
*
* @param {String} type The type associated with the event.
* @param {Object} [metadata] Any metadata to attach to the event.
* @param {Boolean} [flush = false] If true, the event will be sent immediately.
*/
this.emit = function(type, metadata, flush) {
this.emit = function(type, metadata) {
context.pushToArray('events', {type: type, timestamp: (new Date()).getTime()});
eventBeacon.emit(type, assign({
uid: context.uid,
metadata: metadata
}), flush);
Comment thread
robertsevernsentient marked this conversation as resolved.
emit(context, EvolvClient.EVENT_EMITTED, type, metadata);
};

// TODO AP-2318 prevent sending confirmations when every stat comes from analytics. Prior to that, these are still needed
/*let getSessionBasedExps = function() {
let sessionBasedExps = {};

((store.configuration && store.configuration._experiments) || []).forEach(function(experiment) {
if (experiment._optimization_metric === 'SESSION') {
sessionBasedExps[experiment.id] = true;
}
});

return sessionBasedExps;
}*/

/**
* Confirm that the consumer has successfully received and applied values, making them eligible for inclusion in
Expand Down Expand Up @@ -295,18 +277,6 @@ function EvolvClient(opts) {
const existingValues = isInternalUser ? existingInternalConfirmations : existingConfirmations;
context.set(confirmationsKey, newConfirmations.concat(existingValues));

confirmableAllocations.forEach(function(alloc) {
// Only confirm for non session based experiments -- session based use the analytics data
// TODO AP-2318 prevent sending confirmations when every stat comes from analytics. Prior to that, these are still needed
// !sessionBasedExps[alloc.eid] && eventBeacon.emit('confirmation', {
eventBeacon.emit('confirmation', {
uid: alloc.uid,
eid: alloc.eid,
cid: alloc.cid
});
});

eventBeacon.flush();
emit(context, EvolvClient.CONFIRMED);
resolve();
return;
Expand Down Expand Up @@ -359,15 +329,6 @@ function EvolvClient(opts) {

context.set('experiments.contaminations', contextContaminations.concat(contaminations));

contaminatableAllocations.forEach(function(alloc) {
eventBeacon.emit('contamination', {
uid: alloc.uid,
eid: alloc.eid,
cid: alloc.cid,
contaminationReason: details
});
});
eventBeacon.flush();
emit(context, EvolvClient.CONTAMINATED);
};

Expand Down Expand Up @@ -413,33 +374,31 @@ function EvolvClient(opts) {
console.log('Evolv: Failed to retrieve client context');
});

if (options.analytics) {
/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "ctx" }]*/
waitFor(context, CONTEXT_INITIALIZED, function (type, ctx) {
contextBeacon.emit(type, context.remoteContext);
});
waitFor(context, CONTEXT_VALUE_ADDED, function (type, key, value, local) {
if (local) {
return;
}
/*eslint no-unused-vars: ["error", { "argsIgnorePattern": "ctx" }]*/
waitFor(context, CONTEXT_INITIALIZED, function (type, ctx) {
contextBeacon.emit(type, context.remoteContext);
});
waitFor(context, CONTEXT_VALUE_ADDED, function (type, key, value, local) {
if (local) {
return;
}

contextBeacon.emit(type, {key: key, value: value});
});
waitFor(context, CONTEXT_VALUE_CHANGED, function (type, key, value, before, local) {
if (local) {
return;
}
contextBeacon.emit(type, {key: key, value: value});
});
waitFor(context, CONTEXT_VALUE_CHANGED, function (type, key, value, before, local) {
if (local) {
return;
}

contextBeacon.emit(type, {key: key, value: value});
});
waitFor(context, CONTEXT_VALUE_REMOVED, function (type, key, local) {
if (local) {
return;
}
contextBeacon.emit(type, {key: key, value: value});
});
waitFor(context, CONTEXT_VALUE_REMOVED, function (type, key, local) {
if (local) {
return;
}

contextBeacon.emit(type, {key: key});
});
}
contextBeacon.emit(type, {key: key});
});

if (options.autoConfirm) {
this.confirm();
Expand All @@ -454,10 +413,7 @@ function EvolvClient(opts) {
* Force all beacons to transmit.
*/
this.flush = function() {
eventBeacon.flush();
if (options.analytics) {
contextBeacon.flush();
}
contextBeacon.flush();
};

/**
Expand All @@ -466,10 +422,7 @@ function EvolvClient(opts) {
* then calling this will allow data to be sent back to Evolv
*/
this.allowEvents = function() {
eventBeacon.unblockAndFlush();
if (options.analytics) {
contextBeacon.unblockAndFlush();
}
contextBeacon.unblockAndFlush();
};

/**
Expand Down
137 changes: 0 additions & 137 deletions src/tests/beacon.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,143 +484,6 @@ describe('beacon', () => {
});
});

describe('test events v1', () => {
it('should use get is the message is short enough - Edge', async() => {
const v1EventEndpoint = 'https://participants.evolv.ai/v1/MYUID/events'
const fetch = chai.spy(() => new Promise(resolve => resolve({ok: true})));
// noinspection JSConstantReassignment
global.window = {
addEventListener: () => null,
fetch: fetch,
navigator: {
userAgent: edgeAgent
}
};
const beacon = new Beacon(v1EventEndpoint, {uid: ''}, '');

let longMessage = 'abc';

beacon.emit('test', {
test: longMessage
}, false);

await new Promise(resolve => setTimeout(resolve, DELAY + 100));

expect(fetch).to.have.been.called(1);
expect(xhrRequests.length).to.equal(0);
expect(fetch).to.have.been.called.with(v1EventEndpoint +'?test=abc&type=test' , {
cache: 'no-cache',
keepalive: true,
method: 'GET'
});
});

it('should use get is the message is short enough - Chrome', async() => {
const v1EventEndpoint = 'https://participants.evolv.ai/v1/MYUID/events'
const fetch = chai.spy(() => new Promise(resolve => resolve({ok: true})));
// noinspection JSConstantReassignment
global.window = {
addEventListener: () => null,
fetch: fetch,
navigator: {
userAgent: chromeAgent
}
};
const beacon = new Beacon(v1EventEndpoint, {uid: ''}, '');

let longMessage = '';
for (let i = 0; i < MICROSOFT_MAX_MESSAGE_SIZE + 1; i++) {
longMessage += 'a';
}

beacon.emit('test', {
test: longMessage
}, false);

await new Promise(resolve => setTimeout(resolve, DELAY + 100));

expect(fetch).to.have.been.called(1);
expect(xhrRequests.length).to.equal(0);
expect(fetch).to.have.been.called.with(v1EventEndpoint +'?test=' + longMessage + '&type=test' , {
cache: 'no-cache',
keepalive: true,
method: 'GET'
});
});

it('should send the message directly to the failover XHRPost if too big - Edge', async() => {
const v1EventEndpoint = 'https://participants.evolv.ai/v1/MYUID/events'
const fetch = chai.spy(() => new Promise(resolve => resolve({ok: true})));
// noinspection JSConstantReassignment
global.window = {
addEventListener: () => null,
fetch: fetch,
navigator: {
userAgent: edgeAgent
}
};
const beacon = new Beacon(v1EventEndpoint, {uid: ''}, '');

let longMessage = '';
for (let i = 0; i < MICROSOFT_MAX_MESSAGE_SIZE + 1; i++) {
longMessage += 'a';
}

beacon.emit('test', {
test: longMessage
}, false);

await new Promise(resolve => setTimeout(resolve, DELAY + 100));

expect(fetch).to.have.been.called(1);
expect(xhrRequests.length).to.equal(0);
expect(fetch).to.have.been.called.with(v1EventEndpoint , {
body: JSON.stringify({
test: longMessage,
type: 'test'
}),
cache: 'no-cache',
keepalive: true,
method: 'POST'
});
});

it('should send the message directly to the failover XHRPost if too big - Chrome', async() => {
const v1EventEndpoint = 'https://participants.evolv.ai/v1/MYUID/events'
const fetch = chai.spy(() => new Promise(resolve => resolve({ok: true})));
// noinspection JSConstantReassignment
global.window = {
addEventListener: () => null,
fetch: fetch,
navigator: {
userAgent: chromeAgent
}
};
const beacon = new Beacon(v1EventEndpoint, {uid: ''}, '');

let longMessage = '';
for (let i = 0; i < DEFAULT_MAX_MESSAGE_SIZE + 1; i++) {
longMessage += 'a';
}

beacon.emit('test', {
test: longMessage
}, false);

await new Promise(resolve => setTimeout(resolve, DELAY + 100));

expect(fetch).to.have.been.called(1);
expect(xhrRequests.length).to.equal(0);
expect(fetch).to.have.been.called.with(v1EventEndpoint , {
body: JSON.stringify({
test: longMessage,
type: 'test'
}),
cache: 'no-cache',
keepalive: true,
method: 'POST'
});
});
});
});
});
Loading