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

Merged
merged 7 commits into from
Jul 9, 2025

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy