Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tracker.getQueueName method #1217

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@snowplow/browser-tracker-core",
"comment": "Expose getQueueName method",
"type": "none"
}
],
"packageName": "@snowplow/browser-tracker-core"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@snowplow/browser-tracker",
"comment": "Add getQueueName tracker method",
"type": "none"
}
],
"packageName": "@snowplow/browser-tracker"
}
2 changes: 2 additions & 0 deletions libraries/browser-tracker-core/src/tracker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,8 @@ export function Tracker(
},

clearUserData: clearUserDataAndCookies,

getQueueName: outQueue.getName,
};

return {
Expand Down
26 changes: 19 additions & 7 deletions libraries/browser-tracker-core/src/tracker/out_queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,27 @@ import { SharedState } from '../state';
import { localStorageAccessible } from '../detectors';
import { LOG, Payload } from '@snowplow/tracker-core';
import { PAYLOAD_DATA_SCHEMA } from './schemata';
import { EventMethod } from './types';

export interface OutQueue {
enqueueRequest: (request: Payload, url: string) => void;
executeQueue: () => void;
setUseLocalStorage: (localStorage: boolean) => void;
setAnonymousTracking: (anonymous: boolean) => void;
setCollectorUrl: (url: string) => void;
setBufferSize: (bufferSize: number) => void;
setBufferSize: (newBufferSize: number) => void;
/**
* Returns the currently used queue name or if the `eventMethod` argument is provided, the queue name for the eventMethod.
*/
getName: (eventMethod?: Exclude<EventMethod, 'beacon'>) => string;
}

/**
* Object handling sending events to a collector.
* Instantiated once per tracker instance.
*
* @param id - The Snowplow function name (used to generate the localStorage key)
* @param sharedSate - Stores reference to the outbound queue so it can unload the page when all queues are empty
* @param sharedState - Stores reference to the outbound queue so it can unload the page when all queues are empty
* @param useLocalStorage - Whether to use localStorage at all
* @param eventMethod - if null will use 'beacon' otherwise can be set to 'post', 'get', or 'beacon' to force.
* @param postPath - The path where events are to be posted
Expand All @@ -67,7 +72,7 @@ export interface OutQueue {
*/
export function OutQueueManager(
id: string,
sharedSate: SharedState,
sharedState: SharedState,
igneel64 marked this conversation as resolved.
Show resolved Hide resolved
useLocalStorage: boolean,
eventMethod: string | boolean,
postPath: string,
Expand Down Expand Up @@ -114,7 +119,7 @@ export function OutQueueManager(
// Resolve all options and capabilities and decide path
path = usePost ? postPath : '/i',
// Different queue names for GET and POST since they are stored differently
queueName = `snowplowOutQueue_${id}_${usePost ? 'post2' : 'get'}`;
queueName = getQueueName(id, usePost ? 'post' : 'get');

// Ensure we don't set headers when beacon is the requested eventMethod as we might fallback to POST
// and end up sending them in older browsers which don't support beacon leading to inconsistencies
Expand All @@ -128,7 +133,9 @@ export function OutQueueManager(
try {
const localStorageQueue = window.localStorage.getItem(queueName);
outQueue = localStorageQueue ? JSON.parse(localStorageQueue) : [];
} catch (e) {}
} catch (e) {
LOG.error('Failed to access window.localStorage queue.');
}
}

// Initialize to and empty array if we didn't get anything out of localStorage
Expand All @@ -137,16 +144,20 @@ export function OutQueueManager(
}

// Used by pageUnloadGuard
sharedSate.outQueues.push(outQueue);
sharedState.outQueues.push(outQueue);

if (useXhr && bufferSize > 1) {
sharedSate.bufferFlushers.push(function (sync) {
sharedState.bufferFlushers.push(function (sync) {
if (!executingQueue) {
executeQueue(sync);
}
});
}

function getQueueName(id: string, method: Exclude<EventMethod, 'beacon'>) {
return `snowplowOutQueue_${id}_${method === 'get' ? 'get' : 'post2'}`;
}

/*
* Convert a dictionary to a querystring
* The context field is the last in the querystring
Expand Down Expand Up @@ -535,6 +546,7 @@ export function OutQueueManager(
setBufferSize: (newBufferSize: number) => {
bufferSize = newBufferSize;
},
getName: (method?: Exclude<EventMethod, 'beacon'>) => (method ? getQueueName(id, method) : queueName),
};

function hasWebKitBeaconBug(useragent: string) {
Expand Down
5 changes: 5 additions & 0 deletions libraries/browser-tracker-core/src/tracker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ export interface BrowserTracker {
*/
clearUserData: (configuration?: ClearUserDataConfiguration) => void;

/**
* Returns the currently used queue name or if the `eventMethod` argument is provided, the queue name for the eventMethod.
*/
getQueueName: (eventMethod?: Exclude<EventMethod, 'beacon'>) => string;

/**
* Add a plugin into the plugin collection after Tracker has already been initialised
* @param configuration - The plugin to add
Expand Down
48 changes: 48 additions & 0 deletions libraries/browser-tracker-core/test/out_queue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,54 @@ describe('OutQueueManager', () => {
(xhrMock as any).onreadystatechange();
};

describe('API', () => {
it('returns the correct queue name', () => {
const postOutQueue = OutQueueManager(
'sp',
new SharedState(),
true,
'post',
'/com.snowplowanalytics.snowplow/tp2',
1,
40000,
0, // maxGetBytes – 0 for no limit
false,
maxQueueSize,
5000,
false,
{},
true,
[401], // retry status codes - override don't retry ones
[401, 505] // don't retry status codes
);

expect(postOutQueue.getName()).toBe('snowplowOutQueue_sp_post2');
expect(postOutQueue.getName('get')).toBe('snowplowOutQueue_sp_get');

const getOutQueue = OutQueueManager(
'sp',
new SharedState(),
true,
'get',
'/com.snowplowanalytics.snowplow/tp2',
1,
40000,
0,
false,
maxQueueSize,
5000,
false,
{},
true,
[],
[]
);

expect(getOutQueue.getName()).toBe('snowplowOutQueue_sp_get');
expect(getOutQueue.getName('post')).toBe('snowplowOutQueue_sp_post2');
});
});

describe('POST requests', () => {
var outQueue: OutQueue;

Expand Down
1 change: 1 addition & 0 deletions trackers/browser-tracker/docs/browser-tracker.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export interface BrowserTracker {
getDomainUserId: () => void;
getDomainUserInfo: () => void;
getPageViewId: () => string;
getQueueName: (eventMethod?: Exclude<EventMethod, "beacon">) => string;
getTabId: () => string | null;
getUserId: () => void;
id: string;
Expand Down
6 changes: 6 additions & 0 deletions trackers/browser-tracker/test/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SharedState, TrackerConfiguration, addTracker } from '@snowplow/browser-tracker-core';

export function createTracker(configuration?: TrackerConfiguration) {
const id = 'sp-' + Math.random();
return addTracker(id, id, '', '', new SharedState(), configuration);
}
24 changes: 24 additions & 0 deletions trackers/browser-tracker/test/tracker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import { SharedState, addTracker } from '@snowplow/browser-tracker-core';
import F from 'lodash/fp';
import { createTracker } from './helpers';

jest.useFakeTimers('modern');

Expand Down Expand Up @@ -276,3 +277,26 @@ describe('Activity tracker behaviour', () => {
expect(secondPageId).toBe(extractPageId(ppl));
});
});

describe('API', () => {
describe('getQueueName', () => {
it('does return the queue name', () => {
let rand = Math.random();
const mathSpy = jest.spyOn(global.Math, 'random');
mathSpy.mockReturnValueOnce(rand);

const postTracker = createTracker();
expect(postTracker?.getQueueName()).toBe(`snowplowOutQueue_sp-${rand}_post2`);
expect(postTracker?.getQueueName('get')).toBe(`snowplowOutQueue_sp-${rand}_get`);

rand = Math.random();
mathSpy.mockReturnValueOnce(rand);

const getTracker = createTracker({ eventMethod: 'get' });
expect(getTracker?.getQueueName()).toBe(`snowplowOutQueue_sp-${rand}_get`);
expect(getTracker?.getQueueName('post')).toBe(`snowplowOutQueue_sp-${rand}_post2`);

mathSpy.mockRestore();
});
});
});