sorentwo/readthis

View on GitHub
CHANGELOG.md

Summary

Maintainability
Test Coverage
## v2.2.0 2018-01-14

- Added: `Cache#clear` now supports `async`, available on Redis 4.0+
- Added: Documentation for serializers and expanders
- Fixed: Preserve existing expiration value when incrementing or decrementing
  keys. There is also additional documentation about the non-atomicity of the
  increment and decrement methods. See [readthis#59][issue-59] for discussion.
- Fixed: Uniformly force key encodings to binary. Not all methods forced
  encoding of the key, which would cause incomatible encoding errors.
- Changed: Automatically duplicate frozen strings when expanding keys.

[issue-59]: https://github.com/sorentwo/readthis/issues/59

## v2.1.0 2017-10-07

- Changed: Allow any redis client version between 3.0 and 5.0

## v2.0.2 2016-12-12

- Fixed: Properly handle writing when the key and value are both UTF-8. Setting
  both the key and value to UTF-8 strings caused differing encodings to be sent
  to Redis. The key was UTF-8 but the value would be ASCII-8BIT, because it was
  compressed and then packed as 8bit integers. The workaround is to force the
  encoding of both strings to binary, something that will always be compatible.

  This makes Readthis actually usable with Non-English keys.

## v2.0.1 2016-07-27

- Fixed: The 2.0.0 release had a typo that rendered it useless.

## v2.0.0 2016-07-27

- Breaking: `nil` values are now rejected from `read_multi` output by default.
  Previously `nil` values were always preserved when fetching with `read_multi`.
  This differed from the `ActiveSupport::Cache` base behaviour and caused bugs
  in Rails 5.0. More details can be seen at [readthis#39][issue-49].

The old fetching behaviour, with `nil` intact, can be achieved by passing the
`retain_nils` flag:

```ruby
cache.read_multi('a', 'b', retain_nils: true)
```

This can also be set as a global option to retain backward compatibility:

```ruby
config.cache_store = :readthis_store, { retain_nils: true }
```

[issue-49]: https://github.com/sorentwo/readthis/issues/49

## v1.5.0 2016-07-18

- Added: `Cache#delete_matched` has been added in a resource efficient way that
  avoids using the "evil" `KEYS` command.

## v1.4.1 2016-07-05

- Fixed: Require lua files relative to the `Script` file itself. This fixes
  loading scripts from Rails or other applications.

## v1.4.0 2016-07-04

- Added: `Readthis::Script`, for dynamically loading and executing lua scripts.
- Added: Use custom `mexpire` to boost refresh performance with multiple keys.
  It is still slower than raw read performance, but much faster than naive
  `multi` expire (~1.5x faster).
- Changed: Generally tighten inline documentation.
- Fixed: Duplicate objects during `dump` operation when using the passthrough.
  When using `fetch` the original value was returned, including any encoding
  information that was prepended. From [readthis#44][issue-44] by @kagux
- Fixed: Only account for 3 bits when detecting serialized values, which fixes
  detection with 4 or more serializers configured. From [readthis#45][issue-45]
  by @kagux.
- Fixed: The max serializer guard would allow up to 8 serializers, which wasn't
  caught by an improper spec. From [readthis#46][issue-46] by @epilgrim.

[issue-44]: https://github.com/sorentwo/readthis/pull/44
[issue-45]: https://github.com/sorentwo/readthis/pull/45
[issue-46]: https://github.com/sorentwo/readthis/pull/46

## v1.3.0 2016-06-08

- Added: Key expiration refreshing on read. When `refresh: true` is set as an
  instance or method option all read operations will refresh the expiration.
- Fixed: Convert float `expires_in` values to the nearest valid integer.
  Typically any value less than 1 was rounded down to 0, which is an invalid
  expiration. Now a value of `0.1` will be rounded up to `1`, the lowest
  possible expiration.

## v1.2.1 2016-04-06

- Fixed: Splat arguments passed to `mget` within Readthis::Cache#read_multi.
  From [readthis#34][issue-34] submitted by @kyohei-shimada.

[issue-34]: https://github.com/sorentwo/readthis/pull/32

## v1.2.0 2015-12-16

- Added: Global connection fault tolerance. Any Redis connection error will
  raise be caught and a `nil` value will be returned instead. For `fetch`
  operations that means the block will yielded, if provided.
  [readthis#26][issue-26]

[issue-26]: https://github.com/sorentwo/readthis/issues/26

## v1.1.0 2015-12-07

- Fixed: Stop overwriting specific options with the default options. [issue-28].
  Discovered and fixed by @tobinibot.
- Fixed: Handle the case when `nil` is explicitly passed as options to `fetch`.
- Changed: All errors now extend from a base `ReadthisError`.

[issue-28]: https://github.com/sorentwo/readthis/issues/28

## v1.0.0 2015-10-05

- Changed: Remove internal `Notifications` module as part of instrumentation
  cleanup.

## v1.0.0-rc.1 2015-09-27

- Fixed: Custom serializers would be encoded correcty, but would be ignored when
  the value was read back out, leaving the encoding flags prefixed to the value.
- Changed: There are no longer direct accessors for `namespace` and
  `expires_in`. Instead, the exposed `options` hash is used as the fallback for
  all operations. For `ActiveSupport` compliance options must be exposed, so this
  prevents configuration drift after initialization. [readthis#21][issue-21]
- Added: More helpful errors are raised when attempting to use a serializer that
  hasn't been configured. [readthis#22][issue-22].

[issue-21]: https://github.com/sorentwo/readthis/issues/21
[issue-22]: https://github.com/sorentwo/readthis/issues/22

## v1.0.0-beta 2015-09-18

- Breaking: This change is necessary for the consistency and portability of
  values going forward. All entities are now written with a set of option flags
  as the initial byte. This flag is later used to determine whether the entity
  was compressed and what was used to marshal it. There are a number of
  advantages to this approach, consistency and reliability being the most
  important. See [readthis#17][pull-17] for additional background.
- Added: Per-entity options can be passed through to any cache method that
  writes a value (`write`, `fetch`, etc). For example, this allows certain
  entities to be cached as JSON while all other entities are cached using
  Marshal. Thanks to @fabn.
- Fixed: A hash containing the cache key is passed as the payload for
  `ActiveSupport::Notifications` instrumentation, rather than the key directly.
  This moves the implementation in-line with the tests for the code, and
  prevents errors from being masked when an error occurs inside an instrumented
  block. [readthis#20][pull-20]. Discovered by @banister and fixed by @workmad3.

[pull-17]: https://github.com/sorentwo/readthis/pull/17
[pull-20]: https://github.com/sorentwo/readthis/pull/20

## v0.8.1 2015-09-04

- Changed: `Readthis::Cache` now has an accessor for the options that were
  passed during initialization. This is primarily to support the session store
  middleware provided by `ActionDispatch`. See [readthis#16][issue-16].
- Fixed: Caching `nil` values is now possible. Previously the value would be
  converted into a blank string, causing a Marshal error when loading the data.
  There is still some non-standard handling of `nil` within `fetch` or
  `fetch_multi`, where a cached `nil` value will always result in a cache miss.
  See [readthis#15][issue-15].
- Fixed: Entity compression was broken, it wouldn't unload data when the
  compressed size was below the compression limit. Data is now decompressed
  when it can the value looks to be compressed, falling back to the initial
  value when decompression fails. See [readthis#13][issue-13] for details.

[issue-13]: https://github.com/sorentwo/readthis/issues/13
[issue-15]: https://github.com/sorentwo/readthis/issues/15
[issue-16]: https://github.com/sorentwo/readthis/issues/16

## v0.8.0 2015-08-26

- Breaking: The initializer now takes a single options argument instead of a
  `url` and `options` separately. This allows the underlying redis client to
  accept any options, rather than just the driver. For example, it's now
  possible to use Readthis with sentinel directly through the configuration.
- Changed: The `hiredis` driver is *no longer the default*. In order to use the
  vastly faster `hiredis` driver you need to pass it in during construction.
  See [readthis#9][issue-9] for more discussion.

[issue-9]: https://github.com/sorentwo/readthis/issues/9

## v0.7.0 2015-08-11

- Changed: Entity initialization uses an options hash rather than keyword
  arguments. This allows flexibility with older Ruby versions (1.9) that aren't
  officially supported.
- Changed: There is no longer a hard dependency on `hiredis`, though it is the
  default. The redis driver can be configured by passing a `driver: :ruby`
  option through to the constructor.

## v0.6.2 2015-04-28

- Fixed: Set expiration during `write_multi`, primarily effecting `fetch_multi`.
  This fixes the real issue underlying the change in `v0.6.1`.

## v0.6.1 2015-04-28

- Changed: Expiration values are always cast to an integer before use in write
  operations. This prevents subtle ActiveSupport bugs where the value would be
  ignored by `setex`.

## v0.6.0 2015-03-09

- Fixed: Safely handle calling `read_multi` without any keys. [Michael Rykov]
- Fixed: Pointed `redis-activesupport` at master. Only effected development and
  testing.
- Added: A `write_multi` method is no available to bulk set keys and values. It
  is used by `fetch_multi` internally to ensure that there are at most two Redis
  calls.

## v0.5.2 2015-01-09

- Fixed: Remove the `pipeline` around `fetch_multi` writing. This will slow down
  `fetch_multi` in cache miss situations for now. It prevents a difficult to
  track down exception in multi-threaded situations.

## v0.5.1 2014-12-30

- Fixed: The `clear` method now accepts an argument for compatibility with other
  caches. The argument is not actually used for anything.
- Changed: The `delete` method will always return a boolean value rather than an
  integer.
- Changed: Avoid multiple instrumentation calls and pool checkouts within
  `fetch_multi` calls.

## v0.5.0 2014-12-12

- Added: All read and write operations are marshalled to and from storage. This
  allows hashes, arrays, etc. to be restored instead of always returning a
  string. Unlike `ActiveSupport::Store::Entity`, no new objects are allocated
  for each entity, reducing GC and improving performance.
- Fixed: Increment/Decrement interface was only accepting two params instead of
  three. Now accepts `amount` as the second parameter.
- Changed: Increment/Decrement no longer use `incby` and `decby`, as they don't
  work with marshalled values. This means they are not entirely atomic, so race
  conditions are possible.

## v0.4.0 2014-12-11

- Added: Force the use of `hiredis` as the adapter. It is dramatically faster,
  but prevents the project from being used in `jruby`. If we get interest from
  some `jruby` projects we can soften the requirement.
- Added: Compression! Adheres to the `ActiveSupport::Store` documentation.
- Fixed: Gracefully handle `nil` passed as `options` to any cache method.

## v0.3.0 2014-12-01

- Added: Use `to_param` for key expansion, only when available. Makes it
  possible to extract a key from any object when ActiveSupport is loaded.
- Added: Expand hashes as cache keys.
- Changed: Use `mget` for `read_multi`, faster and more synchronous than relying on
  `pipelined`.
- Changed: Delimit compound objects with a slash rather than a colon.

## v0.2.0 2014-11-24

- Added: Instrument all caching methods. Will use `ActiveSupport::Notifications`
  if available, otherwise falls back to a polyfill.
- Added: Expand objects with a `cache_key` method and arrays of strings or objects into
  consistent naespaced keys.

## v0.1.0 2014-11-22

- Initial release! Working as a drop in replacement for `redis_store`.