1. 08 Nov, 2021 1 commit
  2. 03 Nov, 2021 4 commits
  3. 17 Aug, 2021 1 commit
  4. 01 Jun, 2021 1 commit
  5. 04 May, 2021 1 commit
  6. 03 May, 2021 2 commits
  7. 02 May, 2021 1 commit
  8. 29 Apr, 2021 1 commit
  9. 28 Apr, 2021 1 commit
  10. 09 Apr, 2021 1 commit
    • Nathan Harris's avatar
      Audit log message severity levels · 03a066f8
      Nathan Harris authored
      Motivation:
      
      Following the SSWG guidelines for libraries and log levels, because much of the library's behavior is expressed in the language and NIO framework as errors and failed ELFs, logging at error is "verbose" and takes away control from developers.
      
      Modifications:
      
      Log messages have been adjusted to more accurately represent when and how the log message should be used, especially when ELFs are failed or errors are thrown.
      
      Result:
      
      Developers won't have log messages at error or critical unless they opt-in from their own code, unless the library has no way of expressing the failure condition through the language.
      03a066f8
  11. 16 Mar, 2021 1 commit
  12. 08 Mar, 2021 2 commits
    • Nathan Harris's avatar
      c8637c1f
    • Lukasa's avatar
      Add support for service discovery. · 1168ed09
      Lukasa authored
      The newly-released Service Discovery framework gives us the interesting
      opportunity to make RediStack aware of complex service discovery tools.
      This patch supplies a simple adaptor to integrat Service Discovery with
      RediStack's pooled client, allowing users to work with arbitrary service
      discovery systems.
      1168ed09
  13. 03 Mar, 2021 1 commit
    • Lukasa's avatar
      Delay connection attempts without addresses. · 338a6f4a
      Lukasa authored and Nathan Harris's avatar Nathan Harris committed
      In some circumstances users may have connection pools configured without
      any SocketAddresses ready to go. This is particularly likely in service
      discovery configurations. Right now, the effect of attempting to use
      such a pool is two fold. First, we'll emit a bunch of error level logs
      telling users we have no addresses. Second, we'll fall into the
      exponential backoff phase of connection establishment.
      
      The first property is annoying, but the second one is actively harmful.
      If your construction is timed incorrectly, we'll have the awkward
      problem of burning a bunch of CPU trying to create connections we know
      we cannot, and then a lengthy delay after the addresses are actually
      configured before we start trying to use them. That's the worst of all
      worlds.
      
      This patch adds logic to detect the attempt to create connections when
      we don't have any configured addresses and delays them. This path should
      improve performance and ergonomics when in this mode.
      338a6f4a
  14. 22 Feb, 2021 1 commit
  15. 16 Feb, 2021 3 commits
  16. 07 Feb, 2021 1 commit
  17. 02 Dec, 2020 4 commits
    • Nathan Harris's avatar
      Refactor RedisCommand into a general use object · 3c671303
      Nathan Harris authored
      Motivation:
      
      RediStack today represents a command as a temporary object for the purpose of writing to the channel.
      
      While it is useful to have an object for that purpose, commands handled in this way require immediate execution
      and aren't available for other purposes.
      
      Commands can serve a better purpose as a lightweight object to support delayed execution,
      so that pipeling as described in issue #63 could be possible.
      
      Modifications:
      
      - Add: `get` overloads for JSON codable interaction on `RedisClient`
      - Add: New `RedisZRangeResultOption` type for better interactions with zrange operations that can optionally return scores
      - Add: New `RedisHashFieldKey` for type-safety when working with Hash field keys much like `RedisKey`
      - Change: A few API types from enums to structs for library evolution
      - Change: `RedisCommandHandler` to operate on a tuple of `RESPValue, EventLoopPromise<RESPValue>` rather than `RedisCommand`
      - Change: `RedisCommand` to be a generic struct with the keyword, arguments, and a transform closure to defer execution
      - Change: Almost all `RedisClient` command extensions to be factory methods on `RedisCommand` instead
      - Change: Many response types to be optional to avoid developers having to do `isNull` checks on their own
      - Change: `RedisClient.send(command:arguments:)` to be generic with `send(_:)` as the signature
      - Rename: RedisClient extensions for scan methods to be more discoverable and legible as `scanHashField`, etc.
      
      Result:
      
      It should be easier to support a clean pipelining API with deferred command execution,
      with extensions being easier for 2nd party developers, and the maintenance overhead of all of the command extensions
      should be a little lighter when it comes to changing HOW commands are sent such as adding a context parameter
      3c671303
    • Nathan Harris's avatar
      61fb40b1
    • Nathan Harris's avatar
      Add historical test matrix to README · ba35a1f9
      Nathan Harris authored
      ba35a1f9
    • Nathan Harris's avatar
      Set Swift 5.2 as the minimum version · b1484916
      Nathan Harris authored
      b1484916
  18. 27 Nov, 2020 1 commit
    • Nathan Harris's avatar
      Rename RedisKeyLifetime to be nested in RedisKey · 8bf26fb6
      Nathan Harris authored
      Motivation:
      
      `RedisKeyLifetime` already has "RedisKey" as a prefix so it naturally fits as a nested type.
      
      Modifications:
      
      - Change: `RedisKeyLifetime` to be nested in `RedisKey` and named `Lifetime`
      - Rename: `RedisKeyLifetime.Lifetime` to `Duration`
      - Deprecate: `RedisKeyLifetime` and the nested type `Lifetime`
      
      Result:
      
      The global namespace is a little less cluttered with the types falling naturally where they already are.
      8bf26fb6
  19. 22 Nov, 2020 3 commits
  20. 18 Oct, 2020 1 commit
  21. 17 Oct, 2020 2 commits
    • Nathan Harris's avatar
      Change RedisConnection to end subscriptions when not allowed · 61cc879e
      Nathan Harris authored
      Motivation:
      
      When `RedisConnection.allowSubscriptions` is set to `false`, the connection could still be in a subscription state
      leaving further commands to fail slowly from a full roundtrip to Redis, rather than succeeding as expected.
      
      This changes the implementation so that it triggers a full unsubscribe from patterns and channels when set to `false`.
      
      Modifications:
      
      - Change: `RedisConnection.allowSubscriptions` to call `unsubscribe()` and `punsubscribe()` when set to `false`
      - Change: `RedisPubSubHandler` to prefix storage of all dictionary keys to avoid name clashes between pattern and channel subscriptions
      
      Result:
      
      Developers should now have more deterministic and unsurprising behavior with PubSub
      in regards to subscription management and connection state.
      61cc879e
    • Nathan Harris's avatar
      Fix [p]unsubscribe from all · e0d47f73
      Nathan Harris authored
      Motivation:
      
      The methods of unsubscribing from all channels / patterns were not working as expected as they need to be special-case handled.
      
      Modifications:
      
      - Change: `RedisPubSubHandler` to be special-case unsubscribe when no arguments are provided
      
      Result:
      
      Developers should now properly be able to unsubscribe from all channels / patterns with a single method call.
      e0d47f73
  22. 15 Oct, 2020 1 commit
    • Nathan Harris's avatar
      Allow repeated commands to same connection in pool · 42e8d4b1
      Nathan Harris authored
      Motivation:
      
      Some Redis commands are very connection specific that have impacts on future access that makes it difficult in the current
      checkout-use-return cycle that `RedisConnectionPool` uses.
      
      Developers need a way to borrow a specific connection, chain several commands together, and then return the connection to the pool.
      
      Modifications:
      
      - Add: `leaseConnection` method to `RedisConnectionPool` which provides a connection from the pool and returns it after a provided closure's ELF resolves
      - Add: `allowSubscriptions` property to `RedisConnection` for controlling the ability to make PubSub subscriptions
      - Add: `RedisClientError.pubsubNotAllowed` case for when `RedisConnection.allowSubscriptions` is set to `false` and a subscription was still attempted
      
      Result:
      
      Developers should now have an "escape hatch" with `RedisConnectionPool` to do limited exclusive chains of operations on a specific connection.
      42e8d4b1
  23. 07 Oct, 2020 3 commits
    • Nathan Harris's avatar
    • Nathan Harris's avatar
      Add default buffer connectionRetryTimeout to avoid literal immediate timeouts · c8cb256b
      Nathan Harris authored
      Motivation:
      
      When trying to allow users to configure the connection retry timeout offset,
      not having a value provided (deadline of `now`) caused all attempts to use the pool to fail.
      
      Modifications:
      
      - Change: RedisConnectionPool to always have a timeout offset defined
      
      Result:
      
      If users don't specify any value, then the default of 60 seconds will be used.
      
      If users specify "nil" (or `.none`) as the timeout, then a minimum of 10 milliseconds will be used to avoid immediate timeouts
      
      Otherwise, use the user's specified `TimeAmount` as the offset of the timeout
      c8cb256b
    • Nathan Harris's avatar
      Add configuration option for RedisConnectionPool lease timeout · 3e28e75b
      Nathan Harris authored
      Motivation:
      
      With RedisConnectionPool a timeout is provided to prevent infinite loops of
      retrying connections, but right now it is hardcoded to 60 seconds.
      
      Users of downstream projects such as Vapor are noticing a "regression" of sorts, as previously
      EventLoopFutures would fail immediately if a connection was not made available.
      
      Modifications:
      
      - Add: `connectionRetryTimeout` parameter to `RedisConnectionPool` initializer that still defaults to 60 seconds
      - Change: RedisConnectionPool to use the new parameter if available to offset a deadline from "now"
      
      Result:
      
      Users can now configure the connection pool to fail immediately if connections are not available.
      3e28e75b
  24. 02 Oct, 2020 1 commit
    • Nathan Harris's avatar
      Resolve PubSub post-commit feedback · e858c0a6
      Nathan Harris authored
      Motivation:
      
      To ship PubSub faster, it was merged to the master branch without a peer review. This commit is to address the critical points of feedback given in a post-commit review.
      
      Modifications:
      
      - Add: New RedisClientError case where a "race condition" of removing a pubsub handler and subscription can happen
      - Add: New state to RedisPubSubHandler for when it has been removed from a ChannelPipeline
      - Change: RedisPubSubHandler to require an `eventLoop` in its initializer
      - Change: The subscribe and unsubscribe methods on RedisPubSubHandler to handle the EventLoop hopping to be thread-safe
      
      Result:
      
      PubSub should have a more robust and thread-safe implementation.
      e858c0a6
  25. 30 Sep, 2020 1 commit
    • Nathan Harris's avatar
      Add support for PubSub · e7b597fc
      Nathan Harris authored
      Motivation:
      
      One of the great features of Redis is being able to subscribe and receive messages published to specific channels
      as a way of acting as a message queue for processing jobs.
      
      PubSub requires a specific understanding of the connection model that can only be implemented directly in this library.
      
      Modifications:
      
      - Add: `RedisPubSubHandler` to sit in front of `RedisCommandHandler` to manage subscription callbacks and Redis registration
      - Add: `publish` and the `pubsub` commands
      - Add: `addPubSubHandler` extension to `NIO.Channel`
      - Add: Type-safe String wrapper of `RedisChannelName` for PubSub methods
      - Add: `pubsubSubscriptionNotFound` error case
      - Add: `isSubscribed` property to `RedisConnection`
      - Add: `availableConnectionCount` and `leasedConnectionCount` properties to `RedisConnectionPool`
      - Add: Metrics for PubSub
      - Add: `makeNewPool` factory method to `RedisConnectionPoolIntegrationTestCase`
      - Change: `RedisClient` to require methods for PubSub management, as they are intrinsicly tied to the client's connection model
      - Change: Parsing of `PING` response for handling special case in PubSub mode
      - Rename: `ActiveConnectionGauge` to `RedisMetrics.IncrementalGauge`
      
      Result:
      
      Developers will now be able to use Redis in PubSub mode with both connections and pools.
      
      This resolves #6
      e7b597fc