Skip to content

feat: add segment source specific identify files - #174

Open
goldenryan wants to merge 1 commit into
redhat-developer:mainfrom
goldenryan:perSourceIdentify
Open

feat: add segment source specific identify files#174
goldenryan wants to merge 1 commit into
redhat-developer:mainfrom
goldenryan:perSourceIdentify

Conversation

@goldenryan

Copy link
Copy Markdown

Fixes #173

@fbricon fbricon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The core idea is sound — making the identify cache key per-Segment-source prevents cross-extension cache collisions. However a couple of issues need addressing before merge:

  1. writeKey typed as any — should be string | undefined to match getSegmentKey()'s return type.
  2. undefined writeKey produces "undefined-identify" cache key — needs a fallback to preserve backward-compatible "identify" when no writeKey exists.
  3. Redundant parameter on private methodgetIdentifyCacheName always receives this.writeKey, so it should just read the field directly.
  4. No tests — the identify-caching logic (skip duplicate, cache miss, per-source isolation) is behavioral and testable.

export class Reporter implements IReporter {

constructor(private analytics?: CoreAnalytics, private cacheService?: CacheService) {
constructor(private analytics?: CoreAnalytics, private cacheService?: CacheService, private writeKey?: any) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

writeKey should be typed string | undefined instead of any — that matches getSegmentKey()'s return type and avoids hiding bugs.

Suggested change
constructor(private analytics?: CoreAnalytics, private cacheService?: CacheService, private writeKey?: any) {
constructor(private analytics?: CoreAnalytics, private cacheService?: CacheService, private writeKey?: string) {

}

private getIdentifyCacheName(writeKey: string): string {
return `${writeKey}-identify`;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Two issues here:

  1. undefined fallback missing — when writeKey is undefined (no segment key in package.json), this produces the string "undefined-identify". Should fall back to "identify" to preserve backward-compatible behavior.

  2. Redundant parameter — this private method is only ever called with this.writeKey. It can just read the field directly.

Suggested change
return `${writeKey}-identify`;
private getIdentifyCacheName(): string {
return this.writeKey ? `${this.writeKey}-identify` : 'identify';
}

(And update the two call sites to this.getIdentifyCacheName() without arguments.)

@fbricon

fbricon commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved telemetry caching so identify events are tracked separately for each write key.
    • Prevented duplicate identify payloads from being incorrectly skipped across different configurations.
    • Applied consistent telemetry behavior in Node.js and web worker environments.

Walkthrough

Changes

Identify cache namespacing

Layer / File(s) Summary
Namespace identify-event cache keys
src/common/impl/reporter.ts
Reporter accepts a write key and uses ${writeKey}-identify for identify-event cache reads and writes.
Wire segment keys into providers
src/node/redHatServiceNodeProvider.ts, src/webworker/redHatServiceWebWorkerProvider.ts
Both providers derive the segment key from packageJson and pass it to Reporter.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: segment-source-specific identify cache files.
Description check ✅ Passed The description is related to the issue and the cache-file change.
Linked Issues check ✅ Passed The changes namespace identify caching per Segment key, preventing global sharing and matching issue #173.
Out of Scope Changes check ✅ Passed The changes appear focused on the linked identify-cache fix with no obvious unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/common/impl/reporter.ts`:
- Around line 28-29: Wrap the identify switch case in braces so the declarations
from getIdentifyCacheName and cacheService?.get are scoped locally, and include
that case’s break inside the block; leave the other switch cases unchanged.
- Line 36: Update the cache persistence call in the reporter method containing
identifyCacheName to await cacheService.put. Keep it inside report()’s existing
try/catch so write failures are handled and propagated through the established
error path before the method returns.
- Around line 28-30: Update the identify deduplication flow around
getIdentifyCacheName and the cacheService value so it stores the send date in
the namespaced cache entry rather than only the payload hash. Compare the
current date against the cached date before sending, ensuring different identify
payloads are still suppressed on the same day, and update the entry with the
current date after a successful send.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b87fd6e0-8c7f-464b-9884-e079b60ea98e

📥 Commits

Reviewing files that changed from the base of the PR and between dc5d2f0 and 09c03a1.

📒 Files selected for processing (3)
  • src/common/impl/reporter.ts
  • src/node/redHatServiceNodeProvider.ts
  • src/webworker/redHatServiceWebWorkerProvider.ts

Comment on lines +28 to +29
const identifyCacheName = this.getIdentifyCacheName(this.writeKey);
const cached = await this.cacheService?.get(identifyCacheName);

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Scope the identify declarations to their switch case.

Biome reports noSwitchDeclarations on Lines 28-29. Wrap the identify case in braces, including its break, so its lexical declarations cannot collide with later cases.

🧰 Tools
🪛 Biome (2.5.3)

[error] 28-28: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 29-29: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/common/impl/reporter.ts` around lines 28 - 29, Wrap the identify switch
case in braces so the declarations from getIdentifyCacheName and
cacheService?.get are scoped locally, and include that case’s break inside the
block; leave the other switch cases unchanged.

Source: Linters/SAST tools

Comment on lines +28 to 30
const identifyCacheName = this.getIdentifyCacheName(this.writeKey);
const cached = await this.cacheService?.get(identifyCacheName);
if (hash === cached) {

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Record the send date, not only the payload hash.

If two identify payloads differ on the same day, their hashes differ and both are sent. That does not enforce the stated “at most once per day” limit per Segment destination; store and check a date in the namespaced cache value.

🧰 Tools
🪛 Biome (2.5.3)

[error] 28-28: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)


[error] 29-29: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

(lint/correctness/noSwitchDeclarations)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/common/impl/reporter.ts` around lines 28 - 30, Update the identify
deduplication flow around getIdentifyCacheName and the cacheService value so it
stores the send date in the namespaced cache entry rather than only the payload
hash. Compare the current date against the cached date before sending, ensuring
different identify payloads are still suppressed on the same day, and update the
entry with the current date after a successful send.

Logger.log(`Sending 'identify' event with\n${payloadString}`);
await this.analytics?.identify(event);
this.cacheService?.put('identify', hash);
this.cacheService?.put(identifyCacheName, hash);

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.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Await the cache write before returning.

CacheService.put() is asynchronous, but this call is fire-and-forget. A failed write can leave the persisted cache stale, and its rejection bypasses report()’s try/catch; use await and handle persistence failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/common/impl/reporter.ts` at line 36, Update the cache persistence call in
the reporter method containing identifyCacheName to await cacheService.put. Keep
it inside report()’s existing try/catch so write failures are handled and
propagated through the established error path before the method returns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

identify event is cached globally once for all segment destinations

2 participants