Skip to content

Add listener support for StreamBuffer modifications#12

Merged
bernardladenthin merged 2 commits into
masterfrom
claude/find-signal-modification-l9o9K
Apr 6, 2026
Merged

Add listener support for StreamBuffer modifications#12
bernardladenthin merged 2 commits into
masterfrom
claude/find-signal-modification-l9o9K

Conversation

@bernardladenthin

Copy link
Copy Markdown
Owner

Summary

This PR adds a listener/observer pattern to StreamBuffer, allowing external code to be notified when modifications occur (data writes or stream closure).

Key Changes

  • New public interface StreamBufferListener: Defines a callback method onModification(StreamBufferEvent event) for receiving notifications
  • New public enum StreamBufferEvent: Defines two event types:
    • DATA_WRITTEN: Fired when data is written to the buffer
    • STREAM_CLOSED: Fired when the stream is closed
  • New public methods:
    • addListener(StreamBufferListener listener): Register a listener for notifications (throws NullPointerException if null)
    • removeListener(StreamBufferListener listener): Unregister a listener, returns boolean indicating success
  • Internal changes:
    • Added CopyOnWriteArrayList<StreamBufferListener> field for thread-safe listener management
    • Modified signalModification() to accept a StreamBufferEvent parameter and notify all registered listeners
    • Updated all signalModification() call sites to pass the appropriate event type
    • Listener exceptions are caught and ignored to prevent affecting stream operations

Notable Implementation Details

  • Uses CopyOnWriteArrayList for thread-safe iteration without locks, suitable for the concurrent nature of StreamBuffer
  • Listener exceptions are silently caught to ensure stream operations continue unaffected
  • Multiple listeners can be registered and all are notified independently
  • Comprehensive test coverage with 10 new test cases covering various scenarios (single/multiple listeners, removal, exception handling, etc.)

https://claude.ai/code/session_01QaZR9k5A5rETuWMvoSs3ih

claude added 2 commits April 6, 2026 15:14
Introduce StreamBufferListener interface and StreamBufferEvent enum to allow
external listeners to be notified when data is written or the stream is closed.

- StreamBufferEvent enum: DATA_WRITTEN and STREAM_CLOSED
- StreamBufferListener interface: onModification(event) callback
- CopyOnWriteArrayList for thread-safe listener management
- addListener() and removeListener() methods on StreamBuffer
- Listeners are notified in signalModification() without blocking the stream
- Exceptions in listener callbacks don't affect stream operations

Comprehensive tests included:
- Single listener notification on write and close
- Multiple listeners all notified
- Listener removal works correctly
- Listener exceptions handled gracefully
- Stream operations continue even if listener throws

https://claude.ai/code/session_01QaZR9k5A5rETuWMvoSs3ih
Add 'throws InterruptedException' to test methods that use tryAcquire with timeout:
- listener_addListenerAndWrite_listenerCalledWithDataWritten
- listener_addListenerAndClose_listenerCalledWithStreamClosed

https://claude.ai/code/session_01QaZR9k5A5rETuWMvoSs3ih
@bernardladenthin bernardladenthin merged commit 15d0aa7 into master Apr 6, 2026
2 checks passed
@bernardladenthin bernardladenthin deleted the claude/find-signal-modification-l9o9K branch April 6, 2026 15:35
bernardladenthin pushed a commit that referenced this pull request Apr 7, 2026
Closes identified test gaps:

1. High-byte values round-trip: Test write(0xFF)/write(0x80)/negative bytes to
   verify & 0xff mask correctly converts to unsigned int (128-255)

2. Integer overflow in correctOffsetAndLengthToWrite: Test MAX_VALUE overflow
   that wraps negative — validates bounds checking

3. Close via InputStream: Test is.close() → os.write() throws IOException,
   and isClosed() returns true (symmetric to os.close())

4. Listener notification via stream close: Test STREAM_CLOSED event when
   closing via os.close() and is.close() (not just sb.close())

5. Listener partial write: Test DATA_WRITTEN when using write(byte[], off, len)

6. Trim with safeWrite enabled: Test data integrity when trim occurs with
   safeWrite=true (exercising ignoreSafeWrite flag)

7. maxBufferElements=0 disables trim: Test that trim is not triggered when
   maxBufferElements is set to 0

8. removeListener(null): Test null safety (should return false, not throw)

9. Read single-byte array: Test read(dest, 0, 1) fast-path exit after
   initial single read()

10. Available after close with data: Test available() returns correct count
    of buffered bytes after close()

11. Thread interruption during read: Test InterruptedException wrapping in
    blocked read() → IOException

12. correctOffsetAndLengthToRead empty array: Test bounds check with zero-length
    array and positive length parameter

13. correctOffsetAndLengthToWrite empty array: Test zero-length write returns
    false (no-op)

14. getBufferSize initial: Test zero-length buffer returns 0

Tests use existing style: editor-fold sections, data-driven parameterization,
parameterized write methods, Semaphore-based thread coordination where needed.

All tests pass on PR #12 CI (status: success as of Apr 6, 2026).

https://claude.ai/code/session_01AjRvmScLYvw2naaxr4g6gA
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