Skip to content

UN-2930 [FIX] Track subscription usage only for successful runs#1620

Merged
chandrasekharan-zipstack merged 1 commit intofeat/UN-2930-plugin-infrastructurefrom
feat/UN-2930-implementation
Nov 11, 2025
Merged

UN-2930 [FIX] Track subscription usage only for successful runs#1620
chandrasekharan-zipstack merged 1 commit intofeat/UN-2930-plugin-infrastructurefrom
feat/UN-2930-implementation

Conversation

@chandrasekharan-zipstack
Copy link
Copy Markdown
Contributor

@chandrasekharan-zipstack chandrasekharan-zipstack commented Oct 30, 2025

What

  • Track subscription usage only for successful API calls and workflow executions
  • Add subscription usage tracking decorator for automatic commit/discard pattern
  • Integrate decorator into Prompt Studio operations (index, answer-prompt)
  • Add workflow completion/failure handlers for defer/commit/discard
  • Implement batch tracking in workers for completed workflows
  • Add platform-service plugin integration for subscription tracking
  • Remove ~79 lines of hardcoded SQL from platform-service, replace with plugin-based approach

Why

  • UN-2930 Bug: Currently tracking subscription usage for ALL executions, including failures
  • Need defer/commit/discard pattern: defer during execution, commit on success, discard on failure
  • Hardcoded SQL in platform-service creates tight coupling and maintenance issues

How

  • We write the usage to redis through platform-service
  • Commit it only on successful API calls
  • On failures, the redis entry is discarded (it has a TTL of 1 day too)

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

Potential Impact Areas (Low Risk):

  1. Prompt Studio Operations:

    • Risk: Decorator wraps index_document() and prompt_responder()
    • Mitigation: Non-blocking design - subscription tracking errors don't fail main operations
    • Testing Required: Verify indexing and prompting still work if plugin unavailable
  2. Workflow Executions:

    • Risk: Added completion/failure handlers
    • Mitigation: Handlers called AFTER workflow completes, non-blocking, errors only logged
    • Testing Required: Verify workflows complete normally regardless of tracking success/failure
  3. Workers Callback Processing:

    • Risk: Additional logic in callback processing
    • Mitigation: Wrapped in try/except, errors logged but don't fail callbacks
    • Testing Required: Verify callbacks still process even if API call fails
  4. Platform Service:

    • Risk: Replaced SQL logic with plugin call
    • Mitigation: Same inputs/outputs, just different implementation path
    • Testing Required: Verify subscription tracking still works correctly

Why Risk is Low:

  • All subscription tracking is non-blocking - failures are logged but don't propagate
  • Decorator pattern doesn't change function signatures or return values
  • Handlers are called at appropriate lifecycle points (after completion, in exception blocks)
  • Platform service plugin maintains exact same behavior, just cleaner code
  • All changes have comprehensive error handling with logging

Related Issues or PRs

Notes on Testing

  • Tested locally for below items
    • Prompt studio calls
    • Workflow runs
    • ETL triggers
    • API deployment calls

Screenshots

N/A - Backend/API changes only, no UI changes

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

…ons only

This PR implements the complete UN-2930 fix to track subscription usage
only for successful API calls and workflow executions.

Key changes:
- Add subscription usage tracking decorator for Django views
- Apply decorator to Prompt Studio index and answer-prompt operations
- Add workflow completion/failure handlers for defer/commit/discard pattern
- Implement batch tracking in workers for completed workflows
- Add platform-service plugin integration for subscription tracking
- Remove hardcoded SQL from platform-service, use plugin-based approach

Components:
1. Decorator (backend/utils/subscription_usage_decorator.py):
   - Auto-commits usage on success
   - Auto-discards usage on failure
   - Non-blocking error handling

2. Prompt Studio Integration:
   - Track usage for index_document()
   - Track usage for prompt_responder()

3. Workflow Integration:
   - Completion handler commits deferred usage for COMPLETED workflows
   - Failure handler discards all deferred usage

4. Workers Integration:
   - Batch commit for successful file executions
   - Calls internal API for efficient batch processing

5. Platform Service:
   - Plugin-based subscription tracking
   - Cleaner separation of concerns

This ensures usage is only recorded when operations actually succeed,
fixing the issue where failed operations were incorrectly tracked.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 30, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/UN-2930-implementation

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 and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

@chandrasekharan-zipstack chandrasekharan-zipstack changed the title UN-2930 [FEAT] Implement subscription tracking for successful executions only (PR #3 of 6) UN-2930 [FIX] Track subscription usage only for successful runs Oct 30, 2025
@athul-rs athul-rs self-requested a review October 30, 2025 10:48
Copy link
Copy Markdown
Contributor

@jaseemjaskp jaseemjaskp left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Copy Markdown
Contributor

@athul-rs athul-rs left a comment

Choose a reason for hiding this comment

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

LGTM

@chandrasekharan-zipstack chandrasekharan-zipstack merged commit 60972b7 into feat/UN-2930-plugin-infrastructure Nov 11, 2025
5 checks passed
@chandrasekharan-zipstack chandrasekharan-zipstack deleted the feat/UN-2930-implementation branch November 11, 2025 04:33
chandrasekharan-zipstack added a commit that referenced this pull request Nov 11, 2025
* UN-2930 [FEAT] Add core plugin infrastructure

Introduce a generic, framework-agnostic plugin system that supports
Django, Flask, and Workers. This foundation enables dynamic loading
of plugins with metadata validation, singleton/non-singleton patterns,
and support for compiled extensions.

Key components:
- Generic PluginManager with plugin discovery and validation
- DjangoPluginManager wrapper for Django apps
- FlaskPluginManager wrapper for Flask apps
- Redis client enhancement (REDIS_USERNAME support)
- Plugin directory exclusions in .gitignore
- Development dependency: debugpy for debugging

This is the first PR in a series for UN-2930, establishing the
infrastructure needed for subscription usage tracking and other
plugin-based features.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Refactored plugin gitignore to avoid explicitly stating plugin names

* Added new plugin loading mechanism to BE
NOTE: Existing mechanism is left untouched to avoid breaking anything

* Addressed code rabbit's review comment

* Minor code rabbit comment addressed, updated docs on adding and using plugins

* misc: Updated plugin discovery to supported nested plugins upto 2 levels

* UN-2930 [FEAT] Enhance plugin_loader with required parameter validation

- Update plugin_loader docstring to clarify plugins_dir and plugins_pkg are required
- Add parameter validation with helpful ValueError message
- Include practical example showing correct usage pattern
- Improves developer experience with clear setup requirements

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* UN-2930 [FIX] Add thread-safety to FlaskPluginManager singleton

- Add threading.Lock at class level to protect singleton instance
- Guard instance creation and state mutations with lock
- Prevent race conditions in multi-threaded Flask environments
- Ensure thread-safe initialization of app, plugins_dir, and plugins_pkg

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* UN-2930 [REFACTOR] Merge nested conditions and simplify exception handling

- Merge nested if statements in FlaskPluginManager.getInstance() into single compound condition
- Remove redundant PermissionError from plugin_manager (OSError parent class covers it)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>

* [MISC] Refactor plugin loading for BE and prompt-service to use centralized get_plugin() mechanism (#1626)

Refactor plugin loading to use centralized get_plugin() mechanism

Replaced manual plugin loading implementations across backend, prompt-service,
and core modules with the new centralized get_plugin() function. This aligns
all plugin loading with the new infrastructure, reduces code duplication, and
simplifies maintenance. Removed obsolete loader files (subscription_loader,
modifier_loader, processor_loader) that are now replaced by get_plugin().

Generated with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>

* UN-2930 [FIX] Track subscription usage only for successful runs (#1620)

UN-2930 [FEAT] Implement subscription tracking for successful executions only

This PR implements the complete UN-2930 fix to track subscription usage
only for successful API calls and workflow executions.

Key changes:
- Add subscription usage tracking decorator for Django views
- Apply decorator to Prompt Studio index and answer-prompt operations
- Add workflow completion/failure handlers for defer/commit/discard pattern
- Implement batch tracking in workers for completed workflows
- Add platform-service plugin integration for subscription tracking
- Remove hardcoded SQL from platform-service, use plugin-based approach

Components:
1. Decorator (backend/utils/subscription_usage_decorator.py):
   - Auto-commits usage on success
   - Auto-discards usage on failure
   - Non-blocking error handling

2. Prompt Studio Integration:
   - Track usage for index_document()
   - Track usage for prompt_responder()

3. Workflow Integration:
   - Completion handler commits deferred usage for COMPLETED workflows
   - Failure handler discards all deferred usage

4. Workers Integration:
   - Batch commit for successful file executions
   - Calls internal API for efficient batch processing

5. Platform Service:
   - Plugin-based subscription tracking
   - Cleaner separation of concerns

This ensures usage is only recorded when operations actually succeed,
fixing the issue where failed operations were incorrectly tracked.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update backend/configuration/config_registry.py

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>

---------

Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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.

4 participants