Skip to content

Conversation

@peter-lawrey
Copy link
Member

@peter-lawrey peter-lawrey commented Nov 20, 2025

Functional changes

Agent and contributor guidance

  • Updated AGENTS.md to:

    • Move from ASCII-7 to ISO-8859-1 while still discouraging smart quotes and non-portable characters.
    • Add explicit tooling hints for catching non-ASCII (for example iconv, IDE inspections).
    • Expand Javadoc guidance with an example of “good vs bad” inline comments.
    • Clarify build expectations (mvn -q clean verify from a clean checkout) and when to open PRs.
    • Add a security review checklist (validation, auth, encoding, resource exhaustion, timing attacks, secrets handling) to be applied on every PR.
    • Fix doc links to point at src/main/docs/decision-log.adoc and src/main/docs/project-requirements.adoc.

EventGroup / priorities / lifecycle

  • EventGroup:

    • Makes runsInsideCoreLoop() null-safe when no core loop is configured.
    • On startup timeout, now throws a TimeoutException with a richer message including rendered state of core and monitor loops plus a thread dump, rather than rethrowing the raw exception.
  • EventGroupBuilder:

    • Ensures the priority set passed to withPriorities is copied into an EnumSet, avoiding external mutation.

    • Documents and enforces that:

      • loops are only created for enabled priorities; handlers targeting unsupported priorities fail fast, and
      • an empty priority set creates a monitor-only group where all application handler registrations are rejected.

Event loops and pausers

  • AbstractLifecycleEventLoop:

    • Marks privateGroup as volatile so group ownership changes are visible across threads.
  • BlockingEventLoop:

    • Uses ExecutorService.execute instead of submit when starting handler runners and annotates isRunningOnThread loop to avoid SpotBugs false positives.
  • MediumEventLoop:

    • Treats parent and service as final transient fields.
    • Clears its thread reference on exit and improves shutdown logging (more precise message and stack trace).
    • Adds additional suppression around the unrolled handler loop to satisfy static analysis and clarifies the “blocking stack trace” message formatting.
  • MonitorEventLoop:

    • Uses execute instead of submit for its internal executor.
    • Switches to Threads.shutdownDaemon and centralises use of EventLoop.DEBUG_ADDING_HANDLERS / DEBUG_REMOVING_HANDLERS.
    • Always clears the loop thread on exit and uses consistent helper methods for loop start/finish notifications.
  • VanillaEventLoop:

    • Simplifies loop-finished logic by factoring out a helper to finish timer and daemon handlers.
    • Removes an unused public closeAll helper which duplicated existing Closeable.closeQuietly behaviour.
  • Threads:

    • forEachThread now null-checks threads obtained reflectively before dereferencing state, improving robustness on exotic executors.
  • ThreadHolder / monitor harness:

    • ThreadHolder.isAlive() no longer throws InvalidEventHandlerException, simplifying monitoring call sites.
    • ThreadMonitorHarness guards against negative actionCallDelay to avoid spurious “monitor delayed” reports.
    • ThreadsThreadHolder.monitorThreadDelayed() now uses a helper to format nanoseconds into milliseconds with tenths precision and logs a clearer message.

Pauser behaviour and accounting

  • BusyPauser:

    • pause(long, TimeUnit) now unconditionally throws UnsupportedOperationException (instead of advertising a TimeoutException it never throws), making the contract explicit and matching its stateless nature.
  • LongPauser:

    • pause() wraps the timed variant and ignores the timeout exception as “effectively infinite”.

    • doPause(long delayNs):

      • Captures the current thread once in a local variable.
      • Only parks when that snapshot is not interrupted.
      • Tracks elapsed time robustly and ensures thread is cleared and pausing is reset in a finally block.
  • MilliPauser:

    • pause(long, TimeUnit) no longer declares TimeoutException and delegates to doPauseMS.
    • doPauseMS(long) mirrors the LongPauser improvements: snapshot of the current thread, safe park, elapsed time accounting, and clearing of thread and pausing in finally.

Disk space monitoring

  • DiskSpaceMonitor:

    • Stores the threshold percentage in an AtomicInteger, exposing getThresholdPercentage() / setThresholdPercentage(int) with thread-safe updates.

    • Uses computeIfAbsent result directly when initialising DiskAttributes.

    • Refines disk-full percentage calculation:

      • Warns when free space falls below thresholdPercentage using a rounded “X.Y% full” figure derived from a double fraction rather than integer division.
    • Logs disk-space check durations via Jvm.perf() with clearer millisecond formatting if a check takes more than 1 ms.

Other core changes

  • Pauser.SleepyWarning.warnSleepy() is explicitly marked as empty (one-time warning work lives in static initialiser).
  • EventLoopThreadHolder and related monitor classes add minor calculations/annotations to satisfy static analysis without changing semantics.

System property semantics and behaviour

  • systemProperties.adoc:

    • Converted to a Chronicle Threads specific reference with a header, toc and explicit column layout.
    • Clarifies boolean semantics (how Jvm.getBoolean interprets flags).
    • Documents the link between disk monitor properties and decision THR-OPS-003.
    • Tightens descriptions for event loop, pauser and monitoring properties so behaviour matches current code.

Non-functional changes

Documentation, architecture and requirements

  • Root README.adoc:

    • Adds standard attributes (:lang: en-GB, :source-highlighter: rouge).

    • Introduces a “Links” section pointing to:

      • project-requirements.adoc, functional-requirements.adoc,
      • architecture-overview.adoc, operational-controls.adoc,
      • thread-safety-guide.adoc, thread-security-review.adoc,
      • thread-performance-targets.adoc, decision-log.adoc, and systemProperties.adoc.
    • Adds an “Advanced Usage Example” showing how to split latency-sensitive and operational tasks across two EventGroups.

  • Requirements and decision docs:

    • Move the main spec from src/main/adoc to src/main/docs and split into:

      • project-requirements.adoc (full functional and non-functional spec, updated to mention priority gating and the monitor-only case),
      • functional-requirements.adoc (tabular summary of key THR-FN-* requirements and their verification),
      • architecture-overview.adoc (full topology, trade-offs, configuration overview),
      • operational-controls.adoc (renamed from thread-operational-controls.adoc, with cross-links to the other docs),
      • thread-safety-guide.adoc (renamed from thread-thread-safety-guide.adoc, expanded cross-links),
      • thread-performance-targets.adoc (now with highlighter and microsecond symbols),
      • thread-security-review.adoc (expanded to include trust zone, ISO 27001 mapping, and dependency posture).
    • Replace the old src/main/adoc/decision-log.adoc with a new src/main/docs/decision-log.adoc:

      • Keeps earlier decisions (single-threaded loops, busy pausers, disk monitoring, Nine-Box taxonomy).
      • Adds THR-FN-005 describing EventGroup priority sets gating handler registration.
  • Documentation references in project-requirements.adoc updated to point at the new filenames (architecture-overview.adoc, operational-controls.adoc, thread-safety-guide.adoc) and to clarify EventGroup behaviour when priority sets are empty.

Build and dependency alignment

  • Root pom.xml:

    • Bumps the imported net.openhft:third-party-bom from 3.27ea5 to 3.27ea7, aligning Chronicle Threads with the latest BOM used across the enterprise stack.

Test and usability improvements

  • Tests updated to reflect new behaviours and improve clarity:

    • Centralised monitor delay tuning into ThreadsTestCommon.setMonitorInitialDelayMs(int) to avoid scattered static mutations.
    • Ensure SystemTimeProvider.CLOCK is reset via a dedicated helper in ThreadsTestCommon after each test.
    • DiskSpaceMonitorTest now records exceptions after raising the threshold, making the test more reliable.
    • Concurrency and event loop tests (EventGroupTest, EventGroupHandlerTest, EventLoopConcurrencyStressTest, LoopIntrospectionTest, MediumEventLoopTest, VanillaEventLoopTest, etc.) have improved assertions, more explicit comments, and cleaner use of ExecutorService.execute / lambdas.
    • Pauser tests (PauserTest, PauserTimeoutTest) acknowledge the BusyPauser contract (timed pause unsupported) and reduce busy-spin in wait loops.
    • Internal tests for monitoring and rendering (EventLoopStateRendererTest, ThreadMonitorHarnessTest) have clearer assertions and helper methods to keep expectations readable.
    • Example and demo tests (for example SingleAndMultiThreadedExample, JLBH benchmarks) are slightly refactored to use loops/arrays instead of repeated variables, improving readability without changing semantics.
  • Miscellaneous non-functional cleanups:

    • Many small Javadoc improvements and clarifications across production and test classes (parameter descriptions, exception docs, reference to related classes).
    • Additional @SuppressWarnings annotations and small refactors to keep static analysis (SpotBugs, Checkstyle, Sonar) clean while preserving behaviour.

@peter-lawrey peter-lawrey changed the title Adv/develop Document Chronicle Threads architecture and harden event-loop, pauser, and monitoring behaviour Nov 20, 2025
@peter-lawrey peter-lawrey changed the title Document Chronicle Threads architecture and harden event-loop, pauser, and monitoring behaviour Clarify Chronicle Threads requirements/docs and tighten event loop, pauser, and disk-monitor behaviour Nov 26, 2025
@sonarqubecloud
Copy link

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.

3 participants