Revision history for Future-IO-Redis

0.001007  2026-04-21
    - Feature: Callback-driven Subscription delivery
        - New on_message($cb) and on_error($cb) setters on
          Async::Redis::Subscription, alongside the existing
          on_reconnect($cb)
        - Callback signature is ($sub, $msg) / ($sub, $err), consistent
          with on_reconnect
        - Message hashref shape matches next(): type, channel, pattern
          (always present, undef for non-pmessage), data
        - Synchronous by default; return a Future from the callback for
          opt-in backpressure (driver awaits it before reading the next
          frame; failed Futures route to on_error)
        - Once on_message is set, next() croaks — sticky callback mode
          for the lifetime of the subscription
        - Default on_error behavior is to die loudly to prevent silent
          zombie subscriptions; register an explicit no-op to swallow
        - Designed for fire-and-forget listeners (channel-layer
          middleware, websocket gateways, background dispatchers) that
          trigger Future::AsyncAwait "lost its returning future"
          warnings with the iterator pattern
    - Behavior change: Async::Redis::disconnect now calls _close on any
      active Subscription before closing the socket, so the
      subscription's driver doesn't trip over an EOF on its pending
      read. Additive — existing iterator-mode callers are unaffected
    - Internal: factored _dispatch_frame and _read_frame_with_reconnect
      out of Subscription::next; shared between the iterator and
      callback paths. Reconnect semantics are identical across both
    - Pattern subscription responses now include pattern => undef on
      non-pmessage frames (previously omitted); no exists() check needed

0.001006  2026-03-16
    - Bug Fix: Pool forwards all connection parameters
        - Pool now passes prefix, client_name, username, request_timeout,
          path, and all other Async::Redis options through to connections
        - Previously these were silently dropped when Pool created connections
    - Bug Fix: Typed error objects for Redis command errors
        - _decode_response now dies with Async::Redis::Error::Redis objects
          instead of plain "Redis error: ..." strings
        - AutoPipeline uses blessed() check instead of string matching,
          fixing false positives for values starting with "Redis error:"
        - Pipeline results contain error objects at failed slot positions
    - Bug Fix: Pool max connection race condition
        - Concurrent acquire() calls could exceed max connections
        - Added _creating counter to track in-flight connection creations
    - Dependency Change: Future::IO bumped to 0.23 (was 0.19)
        - Future::IO 0.22+ broke load_impl('IOAsync') by adding a poll
          method check that IO::Async's impl doesn't satisfy
        - Removed IO::Async as a test dependency entirely
        - Tests now use Future::IO's built-in poll-based default impl
        - Test suite is fully event-loop agnostic
    - Examples: pagi-chat stats timer uses Future::IO instead of IO::Async

0.001005  2026-03-15
    - Feature: Unix domain socket connections
        - Connect via path parameter or redis+unix:// URI scheme
        - Constructor stores path and skips host/port for unix sockets
        - Added docker-compose redis-unix service for testing
    - Feature: PubSub auto-resubscribe on reconnect
        - Subscriptions automatically re-established after connection drop
        - on_reconnect callback on Subscription object for notification
        - _read_pubsub_frame checks connected state to fail fast
        - _reset_connection now clears in_pubsub flag
    - Bug Fix: _reset_connection left in_pubsub=1 after disconnect
        - Prevented reconnection because AUTH/SELECT blocked by pubsub guard

0.001004  2026-02-02
    - Bug Fix: Socket close ordering
        - Fixed Future::IO corruption when disconnect() called with active watchers
        - Cancel _current_read_future before socket close ensures Future::IO
          unregisters watchers while fileno is still valid
        - Let Perl's DESTROY handle close() after futures are cancelled
    - Breaking Change: Future::IO configuration
        - Removed Future::IO->load_best_impl from module
        - Libraries should not configure Future::IO - only application entry
          points should (following LeoNerd's guidance)
        - Added comprehensive EVENT LOOP CONFIGURATION documentation section
        - Updated SYNOPSIS with proper configuration guidance
    - Improvements:
        - Apply connect_timeout to Redis handshake (AUTH, SELECT, CLIENT SETNAME)
        - Removed unused read_timeout and write_timeout settings
    - Examples:
        - Updated pagi-chat example for PAGI 0.001016 auto-configured Future::IO
    - Testing:
        - New t/93-socket-cleanup/close-with-watchers.t for disconnect scenarios
        - Enhanced t/10-connection/socket-cleanup.t

0.001003  2026-01-18
    - New Feature: Enhanced Lua Script Helper API
        - define_command() for registering named scripts with metadata
        - run_script() for executing registered scripts by name
        - get_script(), list_scripts() for registry access
        - preload_scripts() for pipeline optimization
        - Automatic EVALSHA with EVAL fallback (NOSCRIPT handling)
        - Pipeline integration via $pipe->run_script()
        - Optional method installation (install => 1)
        - Support for fixed or dynamic key counts
    - Script.pm Enhancements:
        - New run() method with explicit keys/args arrays
        - New run_on() method for explicit connection targeting
        - Metadata fields: name, num_keys, description
    - Documentation:
        - New LUA SCRIPTING section in Async::Redis POD
        - Comprehensive examples for all script methods
        - Pipeline integration examples
    - Testing:
        - t/60-scripting/define-command.t (18 tests)
        - t/60-scripting/script-registry.t (17 tests)
        - t/60-scripting/pipeline-scripts.t (16 tests)
        - t/60-scripting/pagi-channels.t (16 tests) - realistic channel layer scenarios

0.001002  2026-01-17
    - Bug Fix: Concurrent command response matching
        - Fixed race condition where multiple async commands on a single
          connection could receive mismatched responses
        - Implemented Response Queue pattern with FIFO ordering
        - Commands now register in inflight queue before sending
        - Single reader coroutine processes responses in order
    - New Features:
        - Added inflight_count() method to check pending commands
        - Added _wait_for_inflight_drain() for pipeline/PubSub synchronization
    - Documentation:
        - Added CONCURRENT COMMANDS section to POD
        - Documented Response Queue pattern and best practices
    - Testing:
        - Added t/92-concurrency/response-ordering.t test suite
        - Tests for concurrent SET, GET, mixed command types
        - Stress test with 100 concurrent commands
        - Inflight tracking verification

0.001001  2026-01-03
    - Initial release
    - Core Features:
        - Full async/await support via Future::IO
        - Event loop agnostic (IO::Async, AnyEvent, UV, etc.)
        - RESP2 protocol support via Protocol::Redis
        - All Redis commands via auto-generated methods
    - Connection Features:
        - TCP and TLS/SSL connections
        - URI connection strings
        - Automatic reconnection with exponential backoff
        - Connection pooling with health checks
        - Fork-safe for pre-fork servers
    - Command Features:
        - Pipelining for improved throughput
        - Transactions (MULTI/EXEC/WATCH)
        - Lua scripting with EVALSHA optimization
        - SCAN iterators (SCAN, HSCAN, SSCAN, ZSCAN)
        - Key prefixing
    - PubSub:
        - Channel and pattern subscriptions
        - Sharded subscriptions (Redis 7+)
    - Observability:
        - OpenTelemetry tracing and metrics
        - Debug logging
        - Credential redaction
    - Testing:
        - Comprehensive test suite
        - Integration tests
        - Performance benchmarks
