Skip to content

Commit f286ece

Browse files
committed
Add tracker.getQueueName method (close #1215)
1 parent 265234f commit f286ece

File tree

9 files changed

+125
-7
lines changed

9 files changed

+125
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/browser-tracker-core",
5+
"comment": "Expose getQueueName method",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/browser-tracker-core"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/browser-tracker",
5+
"comment": "Add getQueueName tracker method",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/browser-tracker"
10+
}

libraries/browser-tracker-core/src/tracker/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,8 @@ export function Tracker(
12831283
},
12841284

12851285
clearUserData: clearUserDataAndCookies,
1286+
1287+
getQueueName: outQueue.getName,
12861288
};
12871289

12881290
return {

libraries/browser-tracker-core/src/tracker/out_queue.ts

+19-7
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,27 @@ import { SharedState } from '../state';
3333
import { localStorageAccessible } from '../detectors';
3434
import { LOG, Payload } from '@snowplow/tracker-core';
3535
import { PAYLOAD_DATA_SCHEMA } from './schemata';
36+
import { EventMethod } from './types';
3637

3738
export interface OutQueue {
3839
enqueueRequest: (request: Payload, url: string) => void;
3940
executeQueue: () => void;
4041
setUseLocalStorage: (localStorage: boolean) => void;
4142
setAnonymousTracking: (anonymous: boolean) => void;
4243
setCollectorUrl: (url: string) => void;
43-
setBufferSize: (bufferSize: number) => void;
44+
setBufferSize: (newBufferSize: number) => void;
45+
/**
46+
* Returns the currently used queue name or if the `eventMethod` argument is provided, the queue name for the eventMethod.
47+
*/
48+
getName: (eventMethod?: Exclude<EventMethod, 'beacon'>) => string;
4449
}
4550

4651
/**
4752
* Object handling sending events to a collector.
4853
* Instantiated once per tracker instance.
4954
*
5055
* @param id - The Snowplow function name (used to generate the localStorage key)
51-
* @param sharedSate - Stores reference to the outbound queue so it can unload the page when all queues are empty
56+
* @param sharedState - Stores reference to the outbound queue so it can unload the page when all queues are empty
5257
* @param useLocalStorage - Whether to use localStorage at all
5358
* @param eventMethod - if null will use 'beacon' otherwise can be set to 'post', 'get', or 'beacon' to force.
5459
* @param postPath - The path where events are to be posted
@@ -67,7 +72,7 @@ export interface OutQueue {
6772
*/
6873
export function OutQueueManager(
6974
id: string,
70-
sharedSate: SharedState,
75+
sharedState: SharedState,
7176
useLocalStorage: boolean,
7277
eventMethod: string | boolean,
7378
postPath: string,
@@ -114,7 +119,7 @@ export function OutQueueManager(
114119
// Resolve all options and capabilities and decide path
115120
path = usePost ? postPath : '/i',
116121
// Different queue names for GET and POST since they are stored differently
117-
queueName = `snowplowOutQueue_${id}_${usePost ? 'post2' : 'get'}`;
122+
queueName = getQueueName(id, usePost ? 'post' : 'get');
118123

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

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

139146
// Used by pageUnloadGuard
140-
sharedSate.outQueues.push(outQueue);
147+
sharedState.outQueues.push(outQueue);
141148

142149
if (useXhr && bufferSize > 1) {
143-
sharedSate.bufferFlushers.push(function (sync) {
150+
sharedState.bufferFlushers.push(function (sync) {
144151
if (!executingQueue) {
145152
executeQueue(sync);
146153
}
147154
});
148155
}
149156

157+
function getQueueName(id: string, method: Exclude<EventMethod, 'beacon'>) {
158+
return `snowplowOutQueue_${id}_${method === 'get' ? 'get' : 'post2'}`;
159+
}
160+
150161
/*
151162
* Convert a dictionary to a querystring
152163
* The context field is the last in the querystring
@@ -535,6 +546,7 @@ export function OutQueueManager(
535546
setBufferSize: (newBufferSize: number) => {
536547
bufferSize = newBufferSize;
537548
},
549+
getName: (method?: Exclude<EventMethod, 'beacon'>) => (method ? getQueueName(id, method) : queueName),
538550
};
539551

540552
function hasWebKitBeaconBug(useragent: string) {

libraries/browser-tracker-core/src/tracker/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,11 @@ export interface BrowserTracker {
580580
*/
581581
clearUserData: (configuration?: ClearUserDataConfiguration) => void;
582582

583+
/**
584+
* Returns the currently used queue name or if the `eventMethod` argument is provided, the queue name for the eventMethod.
585+
*/
586+
getQueueName: (eventMethod?: Exclude<EventMethod, 'beacon'>) => string;
587+
583588
/**
584589
* Add a plugin into the plugin collection after Tracker has already been initialised
585590
* @param configuration - The plugin to add

libraries/browser-tracker-core/test/out_queue.test.ts

+48
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,54 @@ describe('OutQueueManager', () => {
5757
(xhrMock as any).onreadystatechange();
5858
};
5959

60+
describe('API', () => {
61+
it('returns the correct queue name', () => {
62+
const postOutQueue = OutQueueManager(
63+
'sp',
64+
new SharedState(),
65+
true,
66+
'post',
67+
'/com.snowplowanalytics.snowplow/tp2',
68+
1,
69+
40000,
70+
0, // maxGetBytes – 0 for no limit
71+
false,
72+
maxQueueSize,
73+
5000,
74+
false,
75+
{},
76+
true,
77+
[401], // retry status codes - override don't retry ones
78+
[401, 505] // don't retry status codes
79+
);
80+
81+
expect(postOutQueue.getName()).toBe('snowplowOutQueue_sp_post2');
82+
expect(postOutQueue.getName('get')).toBe('snowplowOutQueue_sp_get');
83+
84+
const getOutQueue = OutQueueManager(
85+
'sp',
86+
new SharedState(),
87+
true,
88+
'get',
89+
'/com.snowplowanalytics.snowplow/tp2',
90+
1,
91+
40000,
92+
0,
93+
false,
94+
maxQueueSize,
95+
5000,
96+
false,
97+
{},
98+
true,
99+
[],
100+
[]
101+
);
102+
103+
expect(getOutQueue.getName()).toBe('snowplowOutQueue_sp_get');
104+
expect(getOutQueue.getName('post')).toBe('snowplowOutQueue_sp_post2');
105+
});
106+
});
107+
60108
describe('POST requests', () => {
61109
var outQueue: OutQueue;
62110

trackers/browser-tracker/docs/browser-tracker.api.md

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export interface BrowserTracker {
7575
getDomainUserId: () => void;
7676
getDomainUserInfo: () => void;
7777
getPageViewId: () => string;
78+
getQueueName: (eventMethod?: Exclude<EventMethod, "beacon">) => string;
7879
getTabId: () => string | null;
7980
getUserId: () => void;
8081
id: string;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { SharedState, TrackerConfiguration, addTracker } from '@snowplow/browser-tracker-core';
2+
3+
export function createTracker(configuration?: TrackerConfiguration) {
4+
const id = 'sp-' + Math.random();
5+
return addTracker(id, id, '', '', new SharedState(), configuration);
6+
}

trackers/browser-tracker/test/tracker.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

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

3435
jest.useFakeTimers('modern');
3536

@@ -276,3 +277,26 @@ describe('Activity tracker behaviour', () => {
276277
expect(secondPageId).toBe(extractPageId(ppl));
277278
});
278279
});
280+
281+
describe('API', () => {
282+
describe('getQueueName', () => {
283+
it('does return the queue name', () => {
284+
let rand = Math.random();
285+
const mathSpy = jest.spyOn(global.Math, 'random');
286+
mathSpy.mockReturnValueOnce(rand);
287+
288+
const postTracker = createTracker();
289+
expect(postTracker?.getQueueName()).toBe(`snowplowOutQueue_sp-${rand}_post2`);
290+
expect(postTracker?.getQueueName('get')).toBe(`snowplowOutQueue_sp-${rand}_get`);
291+
292+
rand = Math.random();
293+
mathSpy.mockReturnValueOnce(rand);
294+
295+
const getTracker = createTracker({ eventMethod: 'get' });
296+
expect(getTracker?.getQueueName()).toBe(`snowplowOutQueue_sp-${rand}_get`);
297+
expect(getTracker?.getQueueName('post')).toBe(`snowplowOutQueue_sp-${rand}_post2`);
298+
299+
mathSpy.mockRestore();
300+
});
301+
});
302+
});

0 commit comments

Comments
 (0)