Skip to content

fix(singleton): Fixed getClient, adjusted variable names, updated docstrings.#458

Merged
Murike merged 3 commits intomainfrom
fix/singleton-getclient
Jan 16, 2026
Merged

fix(singleton): Fixed getClient, adjusted variable names, updated docstrings.#458
Murike merged 3 commits intomainfrom
fix/singleton-getclient

Conversation

@Murike
Copy link
Contributor

@Murike Murike commented Jan 12, 2026

User description

(TS SDK Parity Effort) Refactor - getClient from Galileo Singleton

[sc-48662] - https://app.shortcut.com/galileo/story/48662/ts-sdk-parity-effort-refactor-getclient-from-galileo-singleton

Description

  • Refactored getClient to return last logger configured
  • Updated variable names
  • Updated docstrings

Generated description

Below is a concise technical summary of the changes proposed in this PR:
Refactors the GalileoSingleton to track the most recently configured logger and fixes the internal key generation logic to correctly utilize project and experiment identifiers. Enhances the logging framework's reliability by integrating AsyncLocalStorage for context propagation and providing comprehensive test coverage for session initialization.

TopicDetails
Singleton Refactor Implements lastAvailableLogger tracking in GalileoSingleton and refactors getClient to return the most recent logger instance for better state management.
Modified files (1)
  • src/singleton.ts
Latest Contributors(2)
UserCommitDate
Murikefix-multilogger-gap-Mu...December 02, 2025
ajaynayak@gmail.comfeat-adding-Session-ma...May 10, 2025
Testing & Context Expands the test suite to validate AsyncLocalStorage context propagation, key precedence, and legacy method compatibility.
Modified files (1)
  • tests/singleton.test.ts
Latest Contributors(1)
UserCommitDate
Murikefix-multilogger-gap-Mu...December 02, 2025
Key Logic & Init Fixes the _getKey method to dynamically generate cache keys from context and environment variables, and adds an init function for session-aware logger setup.
Modified files (1)
  • src/singleton.ts
Latest Contributors(2)
UserCommitDate
Murikefix-multilogger-gap-Mu...December 02, 2025
ajaynayak@gmail.comfeat-adding-Session-ma...May 10, 2025
This pull request is reviewed by Baz. Review like a pro on (Baz).

Copy link

@fernandocorreia-galileo fernandocorreia-galileo left a comment

Choose a reason for hiding this comment

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

I'm approving, but there is a minor issue that we should fix. It's up to you if you want to do that on this PR, it's probably better to do in a follow-up PR.

Direct terminate() bypass (conceptual): If users call logger.terminate() directly instead of using reset(), lastAvailableLogger could reference a terminated logger. This violates the intended API usage pattern but is technically possible.

Here's a simple, defensive approach - modify getClient() to verify that lastAvailableLogger is still in the active loggers map:

  public getClient(): GalileoLogger {
    // Verify lastAvailableLogger is still active
    if (this.lastAvailableLogger) {
      // Check if this logger is still in our active loggers map
      const isStillActive = Array.from(this.galileoLoggers.values()).includes(
        this.lastAvailableLogger
      );
      if (isStillActive) {
        return this.lastAvailableLogger;
      }
      // Logger was removed/terminated externally, clear the reference
      this.lastAvailableLogger = null;
    }
    return this.getLogger();
  }

Why this works:

  • If someone calls reset(), the logger is removed from the map AND lastAvailableLogger is nullified (✓ already works)
  • If someone calls terminate() directly, the logger stays in the map, so getClient() still returns it (⚠️ still returns terminated logger, but that's user error)
  • If someone manually removes a logger from the map somehow, this check catches it

Even simpler alternative - just always fallback if there's any doubt:

  public getClient(): GalileoLogger {
    return this.lastAvailableLogger ?? this.getLogger();
  }

And add a comment documenting that users should use reset() instead of calling terminate() directly.

My recommendation: The current code is actually fine as-is. The simple fix would be to add a JSDoc comment to getClient():

  /**
   * Returns the last available logger instance, or creates a new one if no logger is available.
   * @deprecated Use getLogger() method instead. This method is kept for backwards compatibility.
   * @important Always use reset() to terminate loggers. Calling terminate() directly may result
   * in getClient() returning a terminated logger instance.
   * @returns An instance of GalileoLogger
   */

This documents the expected usage pattern without adding complexity.

@Murike
Copy link
Contributor Author

Murike commented Jan 16, 2026

I'm approving, but there is a minor issue that we should fix. It's up to you if you want to do that on this PR, it's probably better to do in a follow-up PR.

Direct terminate() bypass (conceptual): If users call logger.terminate() directly instead of using reset(), lastAvailableLogger could reference a terminated logger. This violates the intended API usage pattern but is technically possible.

Here's a simple, defensive approach - modify getClient() to verify that lastAvailableLogger is still in the active loggers map:

  public getClient(): GalileoLogger {
    // Verify lastAvailableLogger is still active
    if (this.lastAvailableLogger) {
      // Check if this logger is still in our active loggers map
      const isStillActive = Array.from(this.galileoLoggers.values()).includes(
        this.lastAvailableLogger
      );
      if (isStillActive) {
        return this.lastAvailableLogger;
      }
      // Logger was removed/terminated externally, clear the reference
      this.lastAvailableLogger = null;
    }
    return this.getLogger();
  }

Why this works:

* If someone calls reset(), the logger is removed from the map AND lastAvailableLogger is nullified (✓ already works)

* If someone calls terminate() directly, the logger stays in the map, so getClient() still returns it (⚠️ still returns terminated logger, but that's user error)

* If someone manually removes a logger from the map somehow, this check catches it

Even simpler alternative - just always fallback if there's any doubt:

  public getClient(): GalileoLogger {
    return this.lastAvailableLogger ?? this.getLogger();
  }

And add a comment documenting that users should use reset() instead of calling terminate() directly.

My recommendation: The current code is actually fine as-is. The simple fix would be to add a JSDoc comment to getClient():

  /**
   * Returns the last available logger instance, or creates a new one if no logger is available.
   * @deprecated Use getLogger() method instead. This method is kept for backwards compatibility.
   * @important Always use reset() to terminate loggers. Calling terminate() directly may result
   * in getClient() returning a terminated logger instance.
   * @returns An instance of GalileoLogger
   */

This documents the expected usage pattern without adding complexity.

Opened ticket to evaluate necessary changes. Logger termination is just a call to flush, doesn't actually disable the logger in any way (including possible singleton references).

@Murike Murike merged commit f291acd into main Jan 16, 2026
8 checks passed
@Murike Murike deleted the fix/singleton-getclient branch January 16, 2026 20:49
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.

2 participants