Skip to content

fix: Fix Duplicate Trace Calls for Async Functions and Optimize Tracer Implementation #473

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

viniciusdsmello
Copy link

Fix: Eliminate Duplicate Trace Calls in Async Functions and Optimize Tracer Implementation

Problem Statement

The Openlayer Python SDK was experiencing duplicate trace calls when using the @trace() decorator on async functions. Instead of generating a single unified trace, async functions created multiple duplicate traces with different data, causing test failures and incorrect tracing behavior.

Root Cause Analysis

The issue was traced to the @trace_async() decorator's incompatibility with async generator functions:

  • The decorator used context managers (with create_step()) that interfered with yield statements
  • This caused wrapper functions to return coroutine objects instead of async_generator objects
  • The context manager became "stuck" waiting for generators to complete before finalizing steps
  • Regular async functions worked correctly, but async generators failed

Solution Implementation

1. Async Generator Detection and Handling

  • Detection: Added inspect.isasyncgenfunction(func) at decoration time to identify async generators
  • Manual Step Management: For async generators, replaced context managers with manual step creation and finalization
  • Preserved Context Managers: Regular async functions continue using context managers for optimal performance
  • Top-Level Yields: Ensured yield statements remain at the top level of wrapper functions

2. Code Optimization (80% Duplication Reduction)

Identified and eliminated massive code duplication across three wrapper functions:

Before: ~150 lines with 80% duplication
After: ~40 lines with extracted helper functions

New Helper Functions:

  • _extract_function_inputs() - Centralized input extraction and cleaning
  • _finalize_step_logging() - Unified step timing and logging
  • _handle_trace_completion() - Consistent trace completion logic
  • _create_step_for_async_generator() - Specialized context manager for async generators

3. Client Authentication Fix

  • Issue: _client was initialized at import time before environment variables were set
  • Solution: Implemented lazy initialization using _get_client() function
  • Result: Client now created when first needed, ensuring API credentials are available

4. Test Refactoring

Created comprehensive nested test scenario with single orchestrator method:

  • New Structure: Single intelligent_assistant_main() method with 7 nested operations
  • Realistic Workflow: Simulates complex AI assistant with preprocessing, intent extraction, context retrieval, synthesis, streaming, validation, post-processing, and logging
  • Single Trace: Generates one comprehensive trace instead of multiple separate tests

…nput extraction and logging finalization

- Introduced `_extract_function_inputs` to streamline input extraction for logging.
- Added `_finalize_step_logging` to encapsulate step timing and logging logic.
- Implemented `_handle_trace_completion` for improved trace completion handling.
- Enhanced `trace_async` decorator to support both async functions and async generators with optimized logging.
- Refactored existing tracing logic to utilize new helper functions for better maintainability and readability.
- Refactored client initialization logic into a new `_get_client` function for better lazy loading.
- Ensured the Openlayer client is only created when needed, improving resource management.
- Updated data streaming calls to utilize the new client retrieval method, enhancing code readability and maintainability.
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.

1 participant