Skip to content

Add transaction observability and task scheduling guards#72

Merged
DiamondDagger590 merged 6 commits into
developfrom
claude/quest-system-audit-july-3u9s9y
Jul 16, 2026
Merged

Add transaction observability and task scheduling guards#72
DiamondDagger590 merged 6 commits into
developfrom
claude/quest-system-audit-july-3u9s9y

Conversation

@DiamondDagger590

@DiamondDagger590 DiamondDagger590 commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

This PR improves observability and safety across the transaction and task scheduling subsystems by:

  1. Adding state tracking to FailSafeTransaction so callers can inspect outcomes
  2. Preventing double-scheduling of RepeatableCoreTask instances
  3. Adding convenience methods to wrapper classes for vanilla/custom type checking
  4. Improving logging consistency across the codebase

Key Changes

Transaction Observability

  • Introduced TransactionState enum (PENDING, COMMITTED, ROLLED_BACK) to track transaction outcomes
  • Added getTransactionState() and getFailureCause() methods to FailSafeTransaction for post-execution inspection
  • Replaced SLF4J logger with Java Logger and improved exception logging to use Logger.log(Level.SEVERE, msg, exception) instead of printStackTrace()
  • Made transaction state fields volatile for thread-safe visibility

Task Scheduling Guards

  • Added guard in RepeatableCoreTask.runTask() to prevent double-scheduling; logs warning and returns if task already executed
  • Made all cross-thread state fields in CoreTask hierarchy volatile (taskExecuted, bukkitTaskId, taskStartTime, taskRunningAsync, paused, delayExpired, currentInterval, cancelled)
  • Updated PlayerUnloadTask to not self-schedule in constructor; callers must explicitly invoke runTask(true) after construction
  • Added tests verifying double-scheduling is ignored and that constructor does not auto-schedule

Wrapper Type Checking

  • Added isVanilla() and isCustom() instance methods to CustomBlockWrapper and CustomEntityWrapper
  • Added static isVanillaBlock(String) and isVanillaEntity(String) methods for identifier-based checking
  • Added comprehensive test coverage for all new methods

Logging & Error Handling

  • Replaced e.printStackTrace() calls with Logger.log(Level.SEVERE, message, exception) in FailSafeTransaction and BatchTransaction
  • Added deduplication of unresolvable material warnings in ItemPluginType using ConcurrentHashMap.newKeySet()
  • Added logger initialization to RepeatableCoreTaskTest setup

Documentation

  • Updated .cursor/rules/core.mdc with new guidelines on constructor task scheduling and logging practices
  • Added comprehensive JavaDoc to new public methods
  • Updated CLAUDE.md with transaction observability and task scheduling patterns

Testing

  • Added TransactionStateTest with enum value and round-trip verification
  • Extended FailSafeTransactionTest to verify state transitions and failure cause capture
  • Added isVanilla() and isCustom() test suites to CustomBlockWrapperTest and CustomEntityWrapperTest
  • Added double-scheduling guard tests to RepeatableCoreTaskTest
  • Updated PlayerUnloadTaskTest to verify constructor does not schedule and runTask() does

Implementation Notes

  • All task state fields are now volatile to ensure visibility across main and async scheduler threads
  • FailSafeTransaction state is captured atomically at commit/rollback boundaries
  • Material warning deduplication uses thread-safe ConcurrentHashMap.newKeySet() to avoid duplicate log spam
  • Constructor-initiated task scheduling is now prohibited across the codebase; all tasks require explicit runTask() calls for testability and clarity

https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX

Summary by CodeRabbit

  • New Features
    • Added transaction outcome tracking for pending, committed, and rolled-back operations, including failure details.
    • Added helpers to identify vanilla and custom blocks and entities.
  • Bug Fixes
    • Prevented repeatable tasks from being scheduled more than once.
    • Improved cancellation and task-state visibility during concurrent execution.
    • Added warnings for unresolved custom materials, shown only once per identifier.
  • Behavior Changes
    • Player unload tasks now require explicit scheduling after creation.
  • Documentation
    • Expanded guidance for task scheduling, transactions, logging, and framework conventions.

claude added 4 commits July 16, 2026 19:33
#63)

- Add re-schedule guard to RepeatableCoreTask.runTask() that logs a warning
  and returns when the task is already scheduled
- Add volatile to cross-thread state fields in CoreTask (bukkitTaskId,
  taskStartTime, taskRunningAsync, taskExecuted), RepeatableCoreTask
  (currentInterval, delayExpired, intervalStartTime, paused), and
  CancelableCoreTask (cancelled)
- Remove self-scheduling from PlayerUnloadTask constructor — callers must
  now call runTask(true) explicitly after construction
- Add RepeatableCoreTaskTest cases for double-scheduling prevention
- Update PlayerUnloadTaskTest to verify constructor does not schedule
- Update CLAUDE.md with anti-pattern and task scheduling notes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX
…rvability (#62)

- Add TransactionState enum (PENDING, COMMITTED, ROLLED_BACK) with
  volatile fields for cross-thread visibility
- Add getTransactionState() and getFailureCause() to FailSafeTransaction
  so callers can inspect outcome without breaking fail-safe semantics
- Replace e.printStackTrace() calls with Logger.log(Level.SEVERE, ..., e)
  to route stack traces through the plugin logger
- Remove unused SLF4J import and field from FailSafeTransaction and
  BatchTransaction
- Add TransactionStateTest for enum round-trip verification
- Add state assertions to existing FailSafeTransactionTest cases
- Update CLAUDE.md domain terminology with TransactionState entry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX
…NE fallback warning (#65)

- Add isVanilla() and isCustom() instance methods to CustomBlockWrapper
  and CustomEntityWrapper for checking whether a wrapper represents a
  vanilla or custom block/entity
- Add isVanillaBlock(String) and isVanillaEntity(String) static methods
  for checking identifiers against the Paper registry without constructing
  a wrapper
- Add dedup-guarded warning to ItemPluginType when material resolution
  fails and falls back to STONE (logs once per unique string)
- Add IsVanilla and IsCustom nested test classes to both wrapper tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX
Add missing entries to .cursor/rules/core.mdc that were added to
CLAUDE.md across the three wave-1 tickets: e.printStackTrace()
anti-pattern, task scheduling notes (volatile fields, re-schedule
guard), and TransactionState observability section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

Claude finished @DiamondDagger590's task in 1m 48s —— View job


Claude PR Review — in progress

  • Gather PR context (diff, changed files)
  • Route to review lenses (security / testing / extensibility — all three apply, diff touches src/main/**/*.java, database/transaction/**, and public API surfaces)
  • Fan out subagents in parallel (running now)
  • Consolidate findings
  • Post final review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@DiamondDagger590, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro

Run ID: 4e3e6c8b-74e7-4f9b-bbfd-d047ecb90c38

📥 Commits

Reviewing files that changed from the base of the PR and between d9863ad and 1540e41.

📒 Files selected for processing (5)
  • .cursor/rules/core.mdc
  • .github/workflows/claude-review.yml
  • src/main/java/com/diamonddagger590/mccore/builder/item/ItemPluginType.java
  • src/main/java/com/diamonddagger590/mccore/util/item/CustomBlockWrapper.java
  • src/main/java/com/diamonddagger590/mccore/util/item/CustomEntityWrapper.java
📝 Walkthrough

Walkthrough

The PR adds transaction outcome tracking and failure accessors, strengthens task scheduling and cross-thread state handling, changes player unload startup to explicit scheduling, de-duplicates unresolved-material warnings, and adds vanilla/custom classification APIs for block and entity wrappers with tests and documentation.

Changes

Transaction outcome tracking

Layer / File(s) Summary
Transaction state contract
src/main/java/com/diamonddagger590/mccore/database/transaction/TransactionState.java, src/main/java/com/diamonddagger590/mccore/database/transaction/FailSafeTransaction.java, .cursor/rules/core.mdc, CLAUDE.md
FailSafeTransaction now exposes PENDING, COMMITTED, and ROLLED_BACK outcomes plus an optional rollback cause.
Execution and logging behavior
src/main/java/com/diamonddagger590/mccore/database/transaction/FailSafeTransaction.java, src/main/java/com/diamonddagger590/mccore/database/transaction/BatchTransaction.java
Transaction failures are recorded and logged through java.util.logging; the batch transaction removes its SLF4J logger.
Transaction outcome tests
src/test/java/com/diamonddagger590/mccore/database/transaction/*
Tests cover initial, committed, and rolled-back states, failure-cause presence, and enum values.

Task lifecycle and concurrency

Layer / File(s) Summary
Cross-thread task state
src/main/java/com/diamonddagger590/mccore/task/core/*, .cursor/rules/core.mdc, CLAUDE.md
Core task execution, cancellation, and interval fields are now volatile.
Scheduling safeguards and startup
src/main/java/com/diamonddagger590/mccore/task/core/RepeatableCoreTask.java, src/main/java/com/diamonddagger590/mccore/task/player/PlayerUnloadTask.java, .cursor/rules/core.mdc, CLAUDE.md
Repeated runTask calls no longer create additional timers, and PlayerUnloadTask requires explicit scheduling after construction.
Scheduling behavior tests
src/test/java/com/diamonddagger590/mccore/task/**
Tests verify duplicate scheduling prevention and explicit PlayerUnloadTask startup.

Item resolution and wrapper queries

Layer / File(s) Summary
Material fallback warnings
src/main/java/com/diamonddagger590/mccore/builder/item/ItemPluginType.java
Unresolvable material strings now produce one warning per distinct string before falling back to stone.
Block and entity classification APIs
src/main/java/com/diamonddagger590/mccore/util/item/CustomBlockWrapper.java, src/main/java/com/diamonddagger590/mccore/util/item/CustomEntityWrapper.java
Wrappers expose vanilla/custom checks and registry-based vanilla lookup helpers.
Wrapper classification tests
src/test/java/com/diamonddagger590/mccore/util/item/*Test.java
Tests cover vanilla and custom wrapper classifications for blocks and entities.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the two main themes of the PR: transaction observability and task scheduling safeguards.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/quest-system-audit-july-3u9s9y

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.

Remove the static WARNED_MATERIALS dedup set and private helper method.
Log the warning directly on every unresolvable material — the spam makes
misconfigured materials obvious to server owners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/diamonddagger590/mccore/builder/item/ItemPluginType.java`:
- Around line 95-96: Bound the WARNED_MATERIALS warning de-duplication cache so
unresolved material strings cannot accumulate for the JVM lifetime. Replace the
unbounded set with a bounded or expiring cache, or add lifecycle-based eviction,
while preserving suppression of repeated warnings within the configured
retention period.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro

Run ID: c1485209-7a85-4c52-a3f4-32c8fd9c9ead

📥 Commits

Reviewing files that changed from the base of the PR and between 92320ee and d9863ad.

📒 Files selected for processing (18)
  • .cursor/rules/core.mdc
  • CLAUDE.md
  • src/main/java/com/diamonddagger590/mccore/builder/item/ItemPluginType.java
  • src/main/java/com/diamonddagger590/mccore/database/transaction/BatchTransaction.java
  • src/main/java/com/diamonddagger590/mccore/database/transaction/FailSafeTransaction.java
  • src/main/java/com/diamonddagger590/mccore/database/transaction/TransactionState.java
  • src/main/java/com/diamonddagger590/mccore/task/core/CancelableCoreTask.java
  • src/main/java/com/diamonddagger590/mccore/task/core/CoreTask.java
  • src/main/java/com/diamonddagger590/mccore/task/core/RepeatableCoreTask.java
  • src/main/java/com/diamonddagger590/mccore/task/player/PlayerUnloadTask.java
  • src/main/java/com/diamonddagger590/mccore/util/item/CustomBlockWrapper.java
  • src/main/java/com/diamonddagger590/mccore/util/item/CustomEntityWrapper.java
  • src/test/java/com/diamonddagger590/mccore/database/transaction/FailSafeTransactionTest.java
  • src/test/java/com/diamonddagger590/mccore/database/transaction/TransactionStateTest.java
  • src/test/java/com/diamonddagger590/mccore/task/core/RepeatableCoreTaskTest.java
  • src/test/java/com/diamonddagger590/mccore/task/player/PlayerUnloadTaskTest.java
  • src/test/java/com/diamonddagger590/mccore/util/item/CustomBlockWrapperTest.java
  • src/test/java/com/diamonddagger590/mccore/util/item/CustomEntityWrapperTest.java
💤 Files with no reviewable changes (1)
  • src/main/java/com/diamonddagger590/mccore/database/transaction/BatchTransaction.java

Comment on lines +95 to +96
private static final Set<String> WARNED_MATERIALS = ConcurrentHashMap.newKeySet();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound the warning de-duplication cache.

WARNED_MATERIALS retains every distinct unresolved string for the lifetime of the JVM. If invalid material values can vary across plugin data or reloads, this becomes an unbounded memory leak and can eventually cause resource exhaustion. Use a bounded/expiring cache or provide lifecycle-based eviction while preserving warning de-duplication.

Also applies to: 128-136

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/diamonddagger590/mccore/builder/item/ItemPluginType.java`
around lines 95 - 96, Bound the WARNED_MATERIALS warning de-duplication cache so
unresolved material strings cannot accumulate for the JVM lifetime. Replace the
unbounded set with a bounded or expiring cache, or add lifecycle-based eviction,
while preserving suppression of repeated warnings within the configured
retention period.

…ow permissions

- Extract private lookupVanillaBlock/lookupVanillaEntityType helpers in
  CustomBlockWrapper and CustomEntityWrapper to consolidate FQN usage
- Update core.mdc e.printStackTrace anti-pattern to reference
  CorePlugin.getInstance().getLogger() instead of Logger.log
- Add Bash(git diff/log/show:*) to allowedTools in claude-review.yml
  so review sub-agents can run git commands

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q76Se6Yvwmjow3t3FSLEX
@DiamondDagger590
DiamondDagger590 merged commit c5761e4 into develop Jul 16, 2026
3 checks passed
@DiamondDagger590
DiamondDagger590 deleted the claude/quest-system-audit-july-3u9s9y branch July 16, 2026 20:22
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