chore(buffer): iron out the buffer issues
This commit is contained in:
49
apps/api/scripts/mock-minimal.json
Normal file
49
apps/api/scripts/mock-minimal.json
Normal file
@@ -0,0 +1,49 @@
|
||||
[
|
||||
{
|
||||
"headers": {
|
||||
"openpanel-client-id": "5b679c47-9ec0-470a-8944-a9ab8f42b14f",
|
||||
"x-client-ip": "221.145.77.175",
|
||||
"user-agent": "Opera/13.66 (Macintosh; Intel Mac OS X 10.8.3 U; GV Presto/2.9.183 Version/11.00)",
|
||||
"origin": "https://classic-hovel.info"
|
||||
},
|
||||
"track": {
|
||||
"type": "track",
|
||||
"payload": {
|
||||
"name": "click_button"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"headers": {
|
||||
"openpanel-client-id": "5b679c47-9ec0-470a-8944-a9ab8f42b14f",
|
||||
"x-client-ip": "221.145.77.175",
|
||||
"user-agent": "Opera/13.66 (Macintosh; Intel Mac OS X 10.8.3 U; GV Presto/2.9.183 Version/11.00)",
|
||||
"origin": "https://classic-hovel.info"
|
||||
},
|
||||
"track": {
|
||||
"type": "track",
|
||||
"payload": {
|
||||
"name": "click_button_2"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"headers": {
|
||||
"openpanel-client-id": "5b679c47-9ec0-470a-8944-a9ab8f42b14f",
|
||||
"x-client-ip": "221.145.77.175",
|
||||
"user-agent": "Opera/13.66 (Macintosh; Intel Mac OS X 10.8.3 U; GV Presto/2.9.183 Version/11.00)",
|
||||
"origin": "https://classic-hovel.info"
|
||||
},
|
||||
"track": {
|
||||
"type": "track",
|
||||
"payload": {
|
||||
"name": "screen_view",
|
||||
"properties": {
|
||||
"__referrer": "https://www.google.com",
|
||||
"__path": "https://classic-hovel.info/beneficium-arcesso-quisquam",
|
||||
"__title": "Hic thesis laboriosam copiose admoveo sufficio."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -140,8 +140,9 @@ function scrambleEvents(events: Event[]) {
|
||||
return events.sort(() => Math.random() - 0.5);
|
||||
}
|
||||
|
||||
// Distribute events over 6 minutes
|
||||
const SIX_MINUTES_MS = 3 * 60 * 1000;
|
||||
// Distribute events over X minutes
|
||||
const MINUTES = 3;
|
||||
const SIX_MINUTES_MS = 1000 * 60 * MINUTES;
|
||||
const startTime = Date.now();
|
||||
let lastTriggeredIndex = 0;
|
||||
|
||||
@@ -155,13 +156,14 @@ async function triggerEvents(file: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventsToTrigger = Math.floor(
|
||||
generatedEvents.length * (elapsedTime / SIX_MINUTES_MS),
|
||||
const eventsToTrigger = Math.min(
|
||||
Math.ceil(generatedEvents.length * (elapsedTime / SIX_MINUTES_MS)),
|
||||
generatedEvents.length,
|
||||
);
|
||||
|
||||
// Send events that haven't been triggered yet
|
||||
for (let i = lastTriggeredIndex; i < eventsToTrigger; i++) {
|
||||
console.log('asbout to send');
|
||||
console.log('about to send');
|
||||
|
||||
const event = generatedEvents[i]!;
|
||||
try {
|
||||
@@ -171,7 +173,7 @@ async function triggerEvents(file: string) {
|
||||
console.error(`Failed to send event ${i + 1}:`, error);
|
||||
}
|
||||
console.log(
|
||||
`sending ${event.track.payload.properties.__path} from user ${event.headers['user-agent']}`,
|
||||
`sending ${event.track.payload?.properties?.__path} from user ${event.headers['user-agent']}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -184,6 +186,8 @@ async function triggerEvents(file: string) {
|
||||
|
||||
if (remainingEvents > 0) {
|
||||
setTimeout(() => triggerEvents(file), 50); // Check every 50ms
|
||||
} else {
|
||||
console.log('All events triggered.');
|
||||
}
|
||||
|
||||
console.log(`Total events to trigger: ${generatedEvents.length}`);
|
||||
|
||||
@@ -43,8 +43,8 @@ export async function postEvent(
|
||||
const locked = await getRedisCache().set(
|
||||
`request:priority:${currentDeviceId}-${previousDeviceId}:${isScreenView ? 'screen_view' : 'other'}`,
|
||||
'locked',
|
||||
'EX',
|
||||
5,
|
||||
'PX',
|
||||
950, // a bit under the delay below
|
||||
'NX',
|
||||
);
|
||||
|
||||
@@ -72,7 +72,7 @@ export async function postEvent(
|
||||
// Prioritize 'screen_view' events by setting no delay
|
||||
// This ensures that session starts are created from 'screen_view' events
|
||||
// rather than other events, maintaining accurate session tracking
|
||||
delay: request.body.name === 'screen_view' ? 0 : 1000,
|
||||
delay: request.body.name === 'screen_view' ? undefined : 1000,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -201,8 +201,8 @@ async function track({
|
||||
const locked = await getRedisCache().set(
|
||||
`request:priority:${currentDeviceId}-${previousDeviceId}:${isScreenView ? 'screen_view' : 'other'}`,
|
||||
'locked',
|
||||
'EX',
|
||||
5,
|
||||
'PX',
|
||||
950, // a bit under the delay below
|
||||
'NX',
|
||||
);
|
||||
|
||||
@@ -228,7 +228,7 @@ async function track({
|
||||
// Prioritize 'screen_view' events by setting no delay
|
||||
// This ensures that session starts are created from 'screen_view' events
|
||||
// rather than other events, maintaining accurate session tracking
|
||||
delay: payload.name === 'screen_view' ? 0 : 1000,
|
||||
delay: payload.name === 'screen_view' ? undefined : 1000,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,17 +39,22 @@ export async function parseIp(ip?: string): Promise<GeoLocation> {
|
||||
}
|
||||
|
||||
try {
|
||||
const geo = await fetch(`${process.env.GEO_IP_HOST}/${ip}`, {
|
||||
const res = await fetch(`${process.env.GEO_IP_HOST}/${ip}`, {
|
||||
signal: AbortSignal.timeout(2000),
|
||||
});
|
||||
const res = (await geo.json()) as RemoteIpLookupResponse;
|
||||
|
||||
if (!res.ok) {
|
||||
return geo;
|
||||
}
|
||||
|
||||
const json = (await res.json()) as RemoteIpLookupResponse;
|
||||
|
||||
return {
|
||||
country: res.country,
|
||||
city: res.city,
|
||||
region: res.stateprov,
|
||||
longitude: res.longitude,
|
||||
latitude: res.latitude,
|
||||
country: json.country,
|
||||
city: json.city,
|
||||
region: json.stateprov,
|
||||
longitude: json.longitude,
|
||||
latitude: json.latitude,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch geo location for ip', { error });
|
||||
|
||||
@@ -9,7 +9,9 @@ export function parseUserAgent(ua?: string | null) {
|
||||
if (!ua) return parsedServerUa;
|
||||
const res = new UAParser(ua).getResult();
|
||||
|
||||
if (isServer(ua)) return parsedServerUa;
|
||||
if (isServer(ua)) {
|
||||
return parsedServerUa;
|
||||
}
|
||||
|
||||
return {
|
||||
os: res.os.name,
|
||||
@@ -77,7 +79,9 @@ function isServer(userAgent: string) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!userAgent.match(/^([^\s]+\/[\d.]+\s*)+$/);
|
||||
// Matches user agents like "Go-http-client/1.0" or "Go Http Client/1.0"
|
||||
// It should just match the first name (with optional spaces) and version
|
||||
return !!userAgent.match(/^[^\/]+\/[\d.]+$/);
|
||||
}
|
||||
|
||||
export function getDevice(ua: string) {
|
||||
|
||||
Reference in New Issue
Block a user