Skip to content

Conversation

@viniciusdsmello
Copy link
Contributor

@viniciusdsmello viniciusdsmello commented Jul 3, 2025

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

Identified and eliminated massive code duplication across three wrapper functions:

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.
viniciusdsmello and others added 4 commits July 8, 2025 15:01
… and maintainability - Introduced `_create_and_initialize_step` to encapsulate step creation and parent-child relationships. - Enhanced `_handle_trace_completion` to streamline trace completion and data streaming logic. - Refactored existing tracing functions to utilize new helper methods, improving code readability. - Added `_log_step_exception` and `_process_wrapper_inputs_and_outputs` for better error handling and input/output processing. - Updated async generator handling to ensure proper tracing during iteration.
…ions - Replaced `_create_step_for_async_generator` with a direct call to `_create_and_initialize_step` to streamline async step creation. - Updated the parameters for step initialization to enhance clarity and maintainability. - Improved overall code readability by reducing function complexity.
@gustavocidornelas gustavocidornelas merged commit d61888c into main Jul 9, 2025
5 checks passed
@gustavocidornelas gustavocidornelas deleted the fixes-trace-async-issues branch July 9, 2025 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants