From e1425dc62418c516af718436463f0c5bebc62942 Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Tue, 1 Mar 2022 21:56:16 +0000 Subject: [PATCH 01/21] Resolve pipelining deprecation warnings --- lib/kredis/migration.rb | 15 ++++++++++++--- lib/kredis/types/proxy.rb | 12 ++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/kredis/migration.rb b/lib/kredis/migration.rb index 3396068..f114562 100644 --- a/lib/kredis/migration.rb +++ b/lib/kredis/migration.rb @@ -5,6 +5,7 @@ class Kredis::Migration def initialize(config = :shared) @redis = Kredis.configured_for config + @pipeline = nil # TODO: Replace script loading with `copy` command once Redis 6.2+ is the minimum supported version. @copy_sha = @redis.script "load", "redis.call('SETNX', KEYS[2], redis.call('GET', KEYS[1])); return 1;" end @@ -23,7 +24,7 @@ def migrate(from:, to:) if to.present? && from != namespaced_to log_migration "Migrating key #{from} to #{namespaced_to}" do - @redis.evalsha @copy_sha, keys: [ from, namespaced_to ] + connection.evalsha @copy_sha, keys: [ from, namespaced_to ] end else log_migration "Skipping blank/unaltered migration key #{from} → #{to}" @@ -32,18 +33,26 @@ def migrate(from:, to:) def delete_all(key_pattern) each_key_batch_matching(key_pattern) do |keys| - @redis.del *keys + connection.del *keys end end private SCAN_BATCH_SIZE = 1_000 + def connection + @pipeline || @redis + end + def each_key_batch_matching(key_pattern, &block) cursor = "0" begin cursor, keys = @redis.scan(cursor, match: key_pattern, count: SCAN_BATCH_SIZE) - @redis.pipelined { yield keys } + @redis.pipelined do |pipeline| + @pipeline = pipeline + yield keys + @pipeline = nil + end end until cursor == "0" end diff --git a/lib/kredis/types/proxy.rb b/lib/kredis/types/proxy.rb index 99033f2..e5eac3f 100644 --- a/lib/kredis/types/proxy.rb +++ b/lib/kredis/types/proxy.rb @@ -2,21 +2,25 @@ class Kredis::Types::Proxy require_relative "proxy/failsafe" include Failsafe - attr_accessor :redis, :key + attr_accessor :redis, :key, :pipeline def initialize(redis, key, **options) @redis, @key = redis, key options.each { |key, value| send("#{key}=", value) } end - def multi(...) - redis.multi(...) + def multi(*args, **kwargs, &block) + redis.multi(*args, **kwargs) do |pipeline| + self.pipeline = pipeline + block.call + self.pipeline = nil + end end def method_missing(method, *args, **kwargs) Kredis.instrument :proxy, **log_message(method, *args, **kwargs) do failsafe do - redis.public_send method, key, *args, **kwargs + (pipeline || redis).public_send method, key, *args, **kwargs end end end From 6c2a8a2d714e366dbddd85c75919bedcd5782f1e Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Mon, 2 May 2022 08:51:28 +0100 Subject: [PATCH 02/21] Revert "Use block parameter to pipeline in Redis#multi (#68)" This reverts commit 88b8c29623fb68bef925963017429d7987ac7687. --- lib/kredis/types/counter.rb | 12 ++++++------ lib/kredis/types/list.rb | 12 ++++++------ lib/kredis/types/set.rb | 14 +++++++------- lib/kredis/types/unique_list.rb | 16 ++++++++-------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/kredis/types/counter.rb b/lib/kredis/types/counter.rb index bcfcf62..cacebb3 100644 --- a/lib/kredis/types/counter.rb +++ b/lib/kredis/types/counter.rb @@ -4,16 +4,16 @@ class Kredis::Types::Counter < Kredis::Types::Proxying attr_accessor :expires_in def increment(by: 1) - multi do |pipeline| - pipeline.set 0, ex: expires_in, nx: true - pipeline.incrby by + multi do + set 0, ex: expires_in, nx: true + incrby by end[-1] end def decrement(by: 1) - multi do |pipeline| - pipeline.set 0, ex: expires_in, nx: true - pipeline.decrby by + multi do + set 0, ex: expires_in, nx: true + decrby by end[-1] end diff --git a/lib/kredis/types/list.rb b/lib/kredis/types/list.rb index cc1867d..cbda3bd 100644 --- a/lib/kredis/types/list.rb +++ b/lib/kredis/types/list.rb @@ -8,16 +8,16 @@ def elements end alias to_a elements - def remove(*elements, pipeline: nil) - types_to_strings(elements, typed).each { |element| (pipeline || proxy).lrem 0, element } + def remove(*elements) + types_to_strings(elements, typed).each { |element| lrem 0, element } end - def prepend(*elements, pipeline: nil) - (pipeline || proxy).lpush types_to_strings(elements, typed) if elements.flatten.any? + def prepend(*elements) + lpush types_to_strings(elements, typed) if elements.flatten.any? end - def append(*elements, pipeline: nil) - (pipeline || proxy).rpush types_to_strings(elements, typed) if elements.flatten.any? + def append(*elements) + rpush types_to_strings(elements, typed) if elements.flatten.any? end alias << append diff --git a/lib/kredis/types/set.rb b/lib/kredis/types/set.rb index dcb79e1..5f7a1e0 100644 --- a/lib/kredis/types/set.rb +++ b/lib/kredis/types/set.rb @@ -8,19 +8,19 @@ def members end alias to_a members - def add(*members, pipeline: nil) - (pipeline || proxy).sadd types_to_strings(members, typed) if members.flatten.any? + def add(*members) + sadd types_to_strings(members, typed) if members.flatten.any? end alias << add - def remove(*members, pipeline: nil) - (pipeline || proxy).srem types_to_strings(members, typed) if members.flatten.any? + def remove(*members) + srem types_to_strings(members, typed) if members.flatten.any? end def replace(*members) - multi do |pipeline| - pipeline.del - add members, pipeline: pipeline + multi do + del + add members end end diff --git a/lib/kredis/types/unique_list.rb b/lib/kredis/types/unique_list.rb index 2a85afc..eb4bbcc 100644 --- a/lib/kredis/types/unique_list.rb +++ b/lib/kredis/types/unique_list.rb @@ -8,10 +8,10 @@ def prepend(elements) elements = Array(elements).uniq return if elements.empty? - multi do |pipeline| - remove elements, pipeline: pipeline - super(elements, pipeline: pipeline) - pipeline.ltrim 0, (limit - 1) if limit + multi do + remove elements + super + ltrim 0, (limit - 1) if limit end end @@ -19,10 +19,10 @@ def append(elements) elements = Array(elements).uniq return if elements.empty? - multi do |pipeline| - remove elements, pipeline: pipeline - super(elements, pipeline: pipeline) - pipeline.ltrim -limit, -1 if limit + multi do + remove elements + super + ltrim -limit, -1 if limit end end alias << append From 7bc291427145a0886a0d094be548829e0b756b95 Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Mon, 2 May 2022 08:57:57 +0100 Subject: [PATCH 03/21] Use a thread-local variable for pipeline --- lib/kredis/migration.rb | 5 ----- lib/kredis/types/proxy.rb | 9 +++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/kredis/migration.rb b/lib/kredis/migration.rb index f107c9f..fa12e68 100644 --- a/lib/kredis/migration.rb +++ b/lib/kredis/migration.rb @@ -5,7 +5,6 @@ class Kredis::Migration def initialize(config = :shared) @redis = Kredis.configured_for config - @pipeline = nil # TODO: Replace script loading with `copy` command once Redis 6.2+ is the minimum supported version. @copy_sha = @redis.script "load", "redis.call('SETNX', KEYS[2], redis.call('GET', KEYS[1])); return 1;" end @@ -40,10 +39,6 @@ def delete_all(key_pattern) private SCAN_BATCH_SIZE = 1_000 - def connection - @pipeline || @redis - end - def each_key_batch_matching(key_pattern, &block) cursor = "0" begin diff --git a/lib/kredis/types/proxy.rb b/lib/kredis/types/proxy.rb index e5eac3f..9a092b2 100644 --- a/lib/kredis/types/proxy.rb +++ b/lib/kredis/types/proxy.rb @@ -2,7 +2,7 @@ class Kredis::Types::Proxy require_relative "proxy/failsafe" include Failsafe - attr_accessor :redis, :key, :pipeline + attr_accessor :redis, :key def initialize(redis, key, **options) @redis, @key = redis, key @@ -11,16 +11,17 @@ def initialize(redis, key, **options) def multi(*args, **kwargs, &block) redis.multi(*args, **kwargs) do |pipeline| - self.pipeline = pipeline + Thread.current[:pipeline] = pipeline block.call - self.pipeline = nil + ensure + Thread.current[:pipeline] = nil end end def method_missing(method, *args, **kwargs) Kredis.instrument :proxy, **log_message(method, *args, **kwargs) do failsafe do - (pipeline || redis).public_send method, key, *args, **kwargs + (Thread.current[:pipeline] || redis).public_send method, key, *args, **kwargs end end end From 476069f57de455f9850c720f3bb93207142ceef7 Mon Sep 17 00:00:00 2001 From: tleish Date: Sat, 18 Jun 2022 06:56:56 -0600 Subject: [PATCH 04/21] Delete list of keys in batch (#90) * Kredis::Migration#delete_all array of keys * Kredis::Migration#delete_all array of keys * Kredis::Migration#delete_all array of keys --- lib/kredis/migration.rb | 12 +++++++++--- test/migration_test.rb | 10 +++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/kredis/migration.rb b/lib/kredis/migration.rb index fa12e68..9b24a30 100644 --- a/lib/kredis/migration.rb +++ b/lib/kredis/migration.rb @@ -30,9 +30,15 @@ def migrate(from:, to:, pipeline: nil) end end - def delete_all(key_pattern) - each_key_batch_matching(key_pattern) do |keys, pipeline| - pipeline.del *keys + def delete_all(*key_patterns) + log_migration "DELETE ALL #{key_patterns.inspect}" do + if key_patterns.length > 1 + @redis.del *key_patterns + else + each_key_batch_matching(key_patterns.first) do |keys, pipeline| + pipeline.del *keys + end + end end end diff --git a/test/migration_test.rb b/test/migration_test.rb index 032385a..40b9c5a 100644 --- a/test/migration_test.rb +++ b/test/migration_test.rb @@ -51,11 +51,19 @@ class MigrationTest < ActiveSupport::TestCase end end - test "delete_all" do + test "delete_all with pattern" do 3.times { |index| Kredis.proxy("mykey:#{index}").set "hello there #{index}" } Kredis::Migration.delete_all "mykey:*" 3.times { |index| assert_nil Kredis.proxy("mykey:#{index}").get } end + + test "delete_all with keys" do + 3.times { |index| Kredis.proxy("mykey:#{index}").set "hello there #{index}" } + + Kredis::Migration.delete_all *3.times.map { |index| "mykey:#{index}" } + + 3.times { |index| assert_nil Kredis.proxy("mykey:#{index}").get } + end end From 4291815a62fd84cfc4cf34445202390733213bdb Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Tue, 21 Jun 2022 15:57:59 +0100 Subject: [PATCH 05/21] Pefer a thread_mattr_accessor over a thread local variable --- lib/kredis.rb | 1 + lib/kredis/types/proxy.rb | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/kredis.rb b/lib/kredis.rb index b65545b..03e8b0b 100644 --- a/lib/kredis.rb +++ b/lib/kredis.rb @@ -1,5 +1,6 @@ require "active_support" require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/module/attribute_accessors_per_thread" require "kredis/version" diff --git a/lib/kredis/types/proxy.rb b/lib/kredis/types/proxy.rb index 9a092b2..dbef792 100644 --- a/lib/kredis/types/proxy.rb +++ b/lib/kredis/types/proxy.rb @@ -4,6 +4,8 @@ class Kredis::Types::Proxy attr_accessor :redis, :key + thread_mattr_accessor :pipeline + def initialize(redis, key, **options) @redis, @key = redis, key options.each { |key, value| send("#{key}=", value) } @@ -11,17 +13,17 @@ def initialize(redis, key, **options) def multi(*args, **kwargs, &block) redis.multi(*args, **kwargs) do |pipeline| - Thread.current[:pipeline] = pipeline + self.pipeline = pipeline block.call ensure - Thread.current[:pipeline] = nil + self.pipeline = nil end end def method_missing(method, *args, **kwargs) Kredis.instrument :proxy, **log_message(method, *args, **kwargs) do failsafe do - (Thread.current[:pipeline] || redis).public_send method, key, *args, **kwargs + (pipeline || redis).public_send method, key, *args, **kwargs end end end From 516c14a486cb00f2da40c835d92716adda195e96 Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Fri, 24 Jun 2022 12:43:14 +0100 Subject: [PATCH 06/21] Coalesce "current pipeline or redis" into the redis method itself Noting that Proxying subclasses that (mistakenly, perhaps) talk to redis directly will need to take care to check for pipeline presence as well. Also remove the redis attr reader from Proxying to prevent mistaken calling of redis without knowledge of the current MULTI state. --- lib/kredis/types/proxy.rb | 8 ++++++-- lib/kredis/types/proxying.rb | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/kredis/types/proxy.rb b/lib/kredis/types/proxy.rb index dbef792..b609a6f 100644 --- a/lib/kredis/types/proxy.rb +++ b/lib/kredis/types/proxy.rb @@ -2,7 +2,7 @@ class Kredis::Types::Proxy require_relative "proxy/failsafe" include Failsafe - attr_accessor :redis, :key + attr_accessor :key thread_mattr_accessor :pipeline @@ -23,12 +23,16 @@ def multi(*args, **kwargs, &block) def method_missing(method, *args, **kwargs) Kredis.instrument :proxy, **log_message(method, *args, **kwargs) do failsafe do - (pipeline || redis).public_send method, key, *args, **kwargs + redis.public_send method, key, *args, **kwargs end end end private + def redis + pipeline || @redis + end + def log_message(method, *args, **kwargs) args = args.flatten.reject(&:blank?).presence kwargs = kwargs.reject { |_k, v| v.blank? }.presence diff --git a/lib/kredis/types/proxying.rb b/lib/kredis/types/proxying.rb index a7c0e55..3607f0f 100644 --- a/lib/kredis/types/proxying.rb +++ b/lib/kredis/types/proxying.rb @@ -1,14 +1,14 @@ require "active_support/core_ext/module/delegation" class Kredis::Types::Proxying - attr_accessor :proxy, :redis, :key + attr_accessor :proxy, :key def self.proxying(*commands) delegate *commands, to: :proxy end def initialize(redis, key, **options) - @redis, @key = redis, key + @key = key @proxy = Kredis::Types::Proxy.new(redis, key) options.each { |key, value| send("#{key}=", value) } end From b11d445f299c31d8d05dd98d32c59d112d32a09a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Barri=C3=A9?= Date: Mon, 22 Aug 2022 15:53:06 +0200 Subject: [PATCH 07/21] Add ltrim to lists See https://redis.io/commands/ltrim/ --- lib/kredis/types/list.rb | 2 +- test/types/list_test.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/kredis/types/list.rb b/lib/kredis/types/list.rb index cbda3bd..9d54cb2 100644 --- a/lib/kredis/types/list.rb +++ b/lib/kredis/types/list.rb @@ -1,5 +1,5 @@ class Kredis::Types::List < Kredis::Types::Proxying - proxying :lrange, :lrem, :lpush, :rpush, :exists?, :del + proxying :lrange, :lrem, :lpush, :ltrim, :rpush, :exists?, :del attr_accessor :typed diff --git a/test/types/list_test.rb b/test/types/list_test.rb index 7e7aa5f..c5a1703 100644 --- a/test/types/list_test.rb +++ b/test/types/list_test.rb @@ -57,4 +57,10 @@ class ListTest < ActiveSupport::TestCase @list.append(%w[ 1 2 3 ]) assert @list.exists? end + + test "ltrim" do + @list.append(%w[ 1 2 3 4 ]) + @list.ltrim(-3, -2) + assert_equal %w[ 2 3 ], @list.elements + end end From 0c1f7115ff4658ebbe02c07f8799e13c637fb8ac Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 22 Aug 2022 11:05:08 +0200 Subject: [PATCH 08/21] Allow Redis 5.x --- Gemfile.lock | 20 ++++++++++++-------- kredis.gemspec | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8b0e16c..549ab10 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ PATH specs: kredis (1.2.0) activesupport (>= 6.0.0) - redis (~> 4.2) + redis (>= 4.2, < 6) GEM remote: https://rubygems.org/ @@ -70,6 +70,7 @@ GEM builder (3.2.4) byebug (11.1.3) concurrent-ruby (1.1.8) + connection_pool (2.2.5) crass (1.0.6) erubi (1.10.0) globalid (0.4.2) @@ -84,17 +85,17 @@ GEM marcel (1.0.1) method_source (1.0.0) mini_mime (1.0.3) - mini_portile2 (2.5.0) + mini_portile2 (2.8.0) minitest (5.14.4) nio4r (2.5.7) - nokogiri (1.11.2) - mini_portile2 (~> 2.5.0) + nokogiri (1.13.8) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.11.2-arm64-darwin) + nokogiri (1.13.8-arm64-darwin) racc (~> 1.4) - nokogiri (1.11.2-x86_64-darwin) + nokogiri (1.13.8-x86_64-darwin) racc (~> 1.4) - racc (1.5.2) + racc (1.6.0) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) @@ -125,7 +126,10 @@ GEM rake (>= 0.8.7) thor (~> 1.0) rake (13.0.3) - redis (4.6.0) + redis (5.0.1) + redis-client (~> 0.7) + redis-client (0.7.1) + connection_pool sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) diff --git a/kredis.gemspec b/kredis.gemspec index d18c80b..68fa156 100644 --- a/kredis.gemspec +++ b/kredis.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.7.0" s.add_dependency "activesupport", ">= 6.0.0" - s.add_dependency "redis", "~> 4.2" + s.add_dependency "redis", ">= 4.2", "< 6" s.add_development_dependency "rails", ">= 6.0.0" s.files = Dir["lib/**/*", "MIT-LICENSE", "README.md"] From 1c2e3a637bcbb60e3fe5965972193c3abc4eef3f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 5 Sep 2022 15:26:37 +0200 Subject: [PATCH 09/21] Bump version for 1.3.0 --- Gemfile.lock | 6 +++--- lib/kredis/version.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 549ab10..582378d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - kredis (1.2.0) + kredis (1.3.0) activesupport (>= 6.0.0) redis (>= 4.2, < 6) @@ -126,9 +126,9 @@ GEM rake (>= 0.8.7) thor (~> 1.0) rake (13.0.3) - redis (5.0.1) + redis (5.0.2) redis-client (~> 0.7) - redis-client (0.7.1) + redis-client (0.7.3) connection_pool sprockets (4.0.2) concurrent-ruby (~> 1.0) diff --git a/lib/kredis/version.rb b/lib/kredis/version.rb index 01fec9a..ac31739 100644 --- a/lib/kredis/version.rb +++ b/lib/kredis/version.rb @@ -1,3 +1,3 @@ module Kredis - VERSION = "1.2.0" + VERSION = "1.3.0" end From 66d63efab82058cd71dc11890592204dcc477046 Mon Sep 17 00:00:00 2001 From: Koo Date: Sat, 17 Dec 2022 01:01:35 +0900 Subject: [PATCH 10/21] Add sample to set (#100) --- lib/kredis/types/set.rb | 10 +++++++++- test/types/set_test.rb | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/kredis/types/set.rb b/lib/kredis/types/set.rb index 5f7a1e0..eabc7a2 100644 --- a/lib/kredis/types/set.rb +++ b/lib/kredis/types/set.rb @@ -1,5 +1,5 @@ class Kredis::Types::Set < Kredis::Types::Proxying - proxying :smembers, :sadd, :srem, :multi, :del, :sismember, :scard, :spop, :exists? + proxying :smembers, :sadd, :srem, :multi, :del, :sismember, :scard, :spop, :exists?, :srandmember attr_accessor :typed @@ -39,4 +39,12 @@ def take def clear del end + + def sample(count = nil) + if count.nil? + string_to_type(srandmember(count), typed) + else + strings_to_types(srandmember(count), typed) + end + end end diff --git a/test/types/set_test.rb b/test/types/set_test.rb index b536262..a9d7bf4 100644 --- a/test/types/set_test.rb +++ b/test/types/set_test.rb @@ -88,4 +88,12 @@ class SetTest < ActiveSupport::TestCase @set.add(%w[ 1 2 3 ]) assert @set.exists? end + + test "srandmember" do + @set = Kredis.set "mylist", typed: :float + @set.add 1.5, 2.7 + + assert @set.sample.in?([ 1.5, 2.7 ]) + assert_equal [ 1.5, 2.7 ], @set.sample(2).sort + end end From ff09f2bea89d1eca7e74e1061c052f9fa6443405 Mon Sep 17 00:00:00 2001 From: Nishiki Liu Date: Fri, 16 Dec 2022 08:02:51 -0800 Subject: [PATCH 11/21] Account for time zones in DateTime serializations (#102) * Use differing time zones in list test This proves the existence of a time zone-related bug where serializing with time zone information breaks equality checks. * Convert Date/DateTimes to UTC before serializing --- lib/kredis/type/datetime.rb | 2 +- test/types/list_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kredis/type/datetime.rb b/lib/kredis/type/datetime.rb index 8841772..fe1bcf4 100644 --- a/lib/kredis/type/datetime.rb +++ b/lib/kredis/type/datetime.rb @@ -4,7 +4,7 @@ module Kredis module Type class DateTime < ActiveModel::Type::DateTime def serialize(value) - super&.iso8601(9) + super&.utc&.iso8601(9) end def cast_value(value) diff --git a/test/types/list_test.rb b/test/types/list_test.rb index c5a1703..551c50c 100644 --- a/test/types/list_test.rb +++ b/test/types/list_test.rb @@ -44,7 +44,7 @@ class ListTest < ActiveSupport::TestCase test "typed as datetime" do @list = Kredis.list "mylist", typed: :datetime - @list.append [ 1.day.from_now.midnight, 2.days.from_now.midnight ] + @list.append [ 1.day.from_now.midnight.in_time_zone("Pacific Time (US & Canada)"), 2.days.from_now.midnight.in_time_zone("UTC") ] assert_equal [ 1.day.from_now.midnight, 2.days.from_now.midnight ], @list.elements @list.remove(2.days.from_now.midnight) From fa58816d04d3f4fce88932d9f6c8002f9f445eda Mon Sep 17 00:00:00 2001 From: dmcge <85393840+dmcge@users.noreply.github.com> Date: Fri, 16 Dec 2022 16:03:35 +0000 Subject: [PATCH 12/21] Address LogSubscriber deprecation (#98) --- lib/kredis/log_subscriber.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kredis/log_subscriber.rb b/lib/kredis/log_subscriber.rb index 75f73f4..08a906b 100644 --- a/lib/kredis/log_subscriber.rb +++ b/lib/kredis/log_subscriber.rb @@ -15,7 +15,7 @@ def meta(event) private def formatted_in(color, event, type: nil) - color " Kredis #{type} (#{event.duration.round(1)}ms) #{event.payload[:message]}", color, true + color " Kredis #{type} (#{event.duration.round(1)}ms) #{event.payload[:message]}", color, bold: true end end From 6243204463f0ca3790b3a093ed14e614d206085d Mon Sep 17 00:00:00 2001 From: Bart de Water <496367+bdewater@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:37:42 -0500 Subject: [PATCH 13/21] Declare Active Model dependency (#107) --- Gemfile.lock | 1 + kredis.gemspec | 1 + 2 files changed, 2 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 582378d..72eb99d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: kredis (1.3.0) + activemodel (>= 6.0.0) activesupport (>= 6.0.0) redis (>= 4.2, < 6) diff --git a/kredis.gemspec b/kredis.gemspec index 68fa156..8125e5d 100644 --- a/kredis.gemspec +++ b/kredis.gemspec @@ -11,6 +11,7 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.7.0" s.add_dependency "activesupport", ">= 6.0.0" + s.add_dependency "activemodel", ">= 6.0.0" s.add_dependency "redis", ">= 4.2", "< 6" s.add_development_dependency "rails", ">= 6.0.0" From e8250a80f50a52eeb2adfcb9b5eb5e477158add8 Mon Sep 17 00:00:00 2001 From: Bart de Water <496367+bdewater@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:44:05 -0500 Subject: [PATCH 14/21] Typecast return of Set#take (#105) --- lib/kredis/types/set.rb | 2 +- test/types/set_test.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/kredis/types/set.rb b/lib/kredis/types/set.rb index eabc7a2..dca921d 100644 --- a/lib/kredis/types/set.rb +++ b/lib/kredis/types/set.rb @@ -33,7 +33,7 @@ def size end def take - spop + string_to_type(spop, typed) end def clear diff --git a/test/types/set_test.rb b/test/types/set_test.rb index a9d7bf4..bd6bc08 100644 --- a/test/types/set_test.rb +++ b/test/types/set_test.rb @@ -72,6 +72,8 @@ class SetTest < ActiveSupport::TestCase @set.remove(2.7) assert_equal [ 1.5 ], @set.members + + assert_equal 1.5, @set.take end test "failing open" do From 459a4cddeffd0dd2fc40493796dd3780f5958867 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Mon, 13 Mar 2023 14:16:42 -0400 Subject: [PATCH 15/21] Fix possible deserialization of untrusted data There is a deserialization of untrusted data vulnerability in the Kredis JSON deserialization code. This vulnerability has been assigned the CVE identifier CVE-2023-27531. Carefully crafted JSON data processed by Kredis may result in deserialization of untrusted data, potentially leading to deserialization of unexpected objects in the system. Any applications using Kredis with JSON are affected. --- lib/kredis/type/json.rb | 2 +- test/types/scalar_test.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/kredis/type/json.rb b/lib/kredis/type/json.rb index 4183d5f..d78b604 100644 --- a/lib/kredis/type/json.rb +++ b/lib/kredis/type/json.rb @@ -8,7 +8,7 @@ def type end def cast_value(value) - JSON.load(value) + JSON.parse(value) end def serialize(value) diff --git a/test/types/scalar_test.rb b/test/types/scalar_test.rb index 03a3ddc..53192e4 100644 --- a/test/types/scalar_test.rb +++ b/test/types/scalar_test.rb @@ -60,6 +60,9 @@ class ScalarTest < ActiveSupport::TestCase json = Kredis.json "myscalar" json.value = { "one" => 1, "string" => "hello" } assert_equal({ "one" => 1, "string" => "hello" }, json.value) + + json.value = {"json_class"=>"String", "raw"=>[97, 98, 99]} + assert_equal({"json_class"=>"String", "raw"=>[97, 98, 99]}, json.value) end test "invalid type" do From 0961d68e779203bcb03d1117d352b5b8103df25d Mon Sep 17 00:00:00 2001 From: Bart de Water <496367+bdewater@users.noreply.github.com> Date: Mon, 29 May 2023 05:45:22 -0400 Subject: [PATCH 16/21] Return Time objects instead of deprecated DateTime (#106) Time is preferred for current dates and times. DateTime is considered deprecated since Ruby 3.0: https://ruby-doc.org/stdlib-3.0.0/libdoc/date/rdoc/DateTime.html --- lib/kredis/type/datetime.rb | 2 +- test/types/scalar_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/kredis/type/datetime.rb b/lib/kredis/type/datetime.rb index fe1bcf4..8d3b6e1 100644 --- a/lib/kredis/type/datetime.rb +++ b/lib/kredis/type/datetime.rb @@ -8,7 +8,7 @@ def serialize(value) end def cast_value(value) - super&.to_datetime + super&.to_time end end end diff --git a/test/types/scalar_test.rb b/test/types/scalar_test.rb index 53192e4..29eacca 100644 --- a/test/types/scalar_test.rb +++ b/test/types/scalar_test.rb @@ -53,7 +53,7 @@ class ScalarTest < ActiveSupport::TestCase test "datetime casting Dates" do datetime = Kredis.datetime "myscalar" datetime.value = Date.current - assert_equal Date.current.to_datetime, datetime.value + assert_equal Date.current.to_time, datetime.value end test "json" do From a0062d18118d284a59366e6ffc5f1cb5aa2f250c Mon Sep 17 00:00:00 2001 From: Lewis Buckley Date: Sun, 18 Jun 2023 16:32:04 +0100 Subject: [PATCH 17/21] Improved version of UniqueList: OrderedSet (#76) * Back UniqueList with a Redis Sorted Set A sorted set is optimal for this type of functionality because we can use fewer, more-performant Redis calls. * Wrap unique list insert and trim in a transaction * Fallback / migration mechanism for existing users of UniqueLists In order to ease the transition from UniqueList being backed by a Redis list, we can fallback to the legacy implementation for read operations. For write operations we first migrate to a sorted set, then retry. * Update the Readme with sorted set backed unique list commands * Test remaining methods with migration fallbacks * Be more specific about which errors to raise * Improve the fallback / migration system * Improve unique list scoring to avoid collisions Use the Redis server time as a basis. Then add the current process time. Then add to that the index of the inserted elements as a microsecond component. * Update Readme with realistic Unique List scores * Implement OrderedSet Like a UniqueList, but backed by a Redis sorted set rather than a list * Resolve pipeline deprecation warnings * Document OrderedSet * Remove UniqueListLegacy * Revert fallback options * Revert change to type_from * Enforce limit is not negative * Revert config proxying * Fix bug in score ge neration --- README.md | 8 +++ lib/kredis/types.rb | 5 ++ lib/kredis/types/ordered_set.rb | 71 +++++++++++++++++++++++ test/types/ordered_set_test.rb | 99 +++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 lib/kredis/types/ordered_set.rb create mode 100644 test/types/ordered_set_test.rb diff --git a/README.md b/README.md index bc99d86..c9b444b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,14 @@ unique_list << "5" # => LREM myuniquelist 0, "5" + R unique_list.remove(3) # => LREM myuniquelist 0, "3" [ "4", "2", "1", "5" ] == unique_list.elements # => LRANGE myuniquelist 0, -1 +ordered_set = Kredis.ordered_set "myorderedset" +ordered_set.append(%w[ 2 3 4 ]) # => ZADD myorderedset 1646131025.4953232 2 1646131025.495326 3 1646131025.4953272 4 +ordered_set.prepend(%w[ 1 2 3 4 ]) # => ZADD myorderedset -1646131025.4957051 1 -1646131025.495707 2 -1646131025.4957082 3 -1646131025.4957092 4 +ordered_set.append([]) +ordered_set << "5" # => ZADD myorderedset 1646131025.4960442 5 +ordered_set.remove(3) # => ZREM myorderedset 3 +[ "4", "2", "1", "5" ] == ordered_set.elements # => ZRANGE myorderedset 0 -1 + set = Kredis.set "myset", typed: :datetime set.add(DateTime.tomorrow, DateTime.yesterday) # => SADD myset "2021-02-03 00:00:00 +0100" "2021-02-01 00:00:00 +0100" set << DateTime.tomorrow # => SADD myset "2021-02-03 00:00:00 +0100" diff --git a/lib/kredis/types.rb b/lib/kredis/types.rb index 16ad906..5338a0c 100644 --- a/lib/kredis/types.rb +++ b/lib/kredis/types.rb @@ -71,6 +71,10 @@ def set(key, typed: :string, config: :shared, after_change: nil) type_from(Set, config, key, after_change: after_change, typed: typed) end + def ordered_set(key, typed: :string, limit: nil, config: :shared, after_change: nil) + type_from(OrderedSet, config, key, after_change: after_change, typed: typed, limit: limit) + end + def slot(key, config: :shared, after_change: nil) type_from(Slots, config, key, after_change: after_change, available: 1) end @@ -99,4 +103,5 @@ def type_from(type_klass, config, key, after_change: nil, **options) require "kredis/types/list" require "kredis/types/unique_list" require "kredis/types/set" +require "kredis/types/ordered_set" require "kredis/types/slots" diff --git a/lib/kredis/types/ordered_set.rb b/lib/kredis/types/ordered_set.rb new file mode 100644 index 0000000..27276ab --- /dev/null +++ b/lib/kredis/types/ordered_set.rb @@ -0,0 +1,71 @@ +class Kredis::Types::OrderedSet < Kredis::Types::Proxying + proxying :multi, :zrange, :zrem, :zadd, :zremrangebyrank, :zcard, :exists?, :del + + attr_accessor :typed + attr_reader :limit + + def elements + strings_to_types(zrange(0, -1) || [], typed) + end + alias to_a elements + + def remove(*elements) + zrem(types_to_strings(elements, typed)) + end + + def prepend(elements) + insert(elements, prepending: true) + end + + def append(elements) + insert(elements) + end + alias << append + + def limit=(limit) + raise "Limit must be greater than 0" if limit && limit <= 0 + + @limit = limit + end + + private + def insert(elements, prepending: false) + elements = Array(elements) + return if elements.empty? + + elements_with_scores = types_to_strings(elements, typed).map.with_index do |element, index| + score = generate_base_score(negative: prepending) + (index / 100000) + + [ score , element ] + end + + multi do |pipeline| + pipeline.zadd(elements_with_scores) + trim(from_beginning: prepending, pipeline: pipeline) + end + end + + def generate_base_score(negative:) + current_time = process_start_time + process_uptime + + negative ? -current_time : current_time + end + + def process_start_time + @process_start_time ||= redis.time.join(".").to_f - process_uptime + end + + def process_uptime + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + def trim(from_beginning:, pipeline:) + return unless limit + + if from_beginning + pipeline.zremrangebyrank(limit, -1) + else + pipeline.zremrangebyrank(0, -(limit + 1)) + end + end +end diff --git a/test/types/ordered_set_test.rb b/test/types/ordered_set_test.rb new file mode 100644 index 0000000..420736e --- /dev/null +++ b/test/types/ordered_set_test.rb @@ -0,0 +1,99 @@ +require "test_helper" + +class OrderedSetTest < ActiveSupport::TestCase + setup { @set = Kredis.ordered_set "ordered-set", limit: 5 } + + test "append" do + @set.append(%w[ 1 2 3 ]) + @set.append(%w[ 1 2 3 4 ]) + assert_equal %w[ 1 2 3 4 ], @set.elements + + @set << "5" + assert_equal %w[ 1 2 3 4 5 ], @set.elements + end + + test "appending the same element re-appends it" do + @set.append(%w[ 1 2 3 ]) + @set.append(%w[ 2 ]) + assert_equal %w[ 1 3 2 ], @set.elements + end + + test "mass append maintains ordering" do + @set = Kredis.ordered_set "ordered-set" # no limit + + thousand_elements = 1000.times.map { [*"A".."Z"].sample(10).join } + @set.append(thousand_elements) + assert_equal thousand_elements, @set.elements + + thousand_elements.each { |element| @set.append(element) } + assert_equal thousand_elements, @set.elements + end + + test "prepend" do + @set.prepend(%w[ 1 2 3 ]) + @set.prepend(%w[ 1 2 3 4 ]) + assert_equal %w[ 4 3 2 1 ], @set.elements + end + + test "append nothing" do + @set.append(%w[ 1 2 3 ]) + @set.append([]) + assert_equal %w[ 1 2 3 ], @set.elements + end + + test "prepend nothing" do + @set.prepend(%w[ 1 2 3 ]) + @set.prepend([]) + assert_equal %w[ 3 2 1 ], @set.elements + end + + test "typed as integers" do + @set = Kredis.ordered_set "mylist", typed: :integer + + @set.append [ 1, 2 ] + @set << 2 + assert_equal [ 1, 2 ], @set.elements + + @set.remove(2) + assert_equal [ 1 ], @set.elements + + @set.append [ "1-a", 2 ] + + assert_equal [ 1, 2 ], @set.elements + end + + test "exists?" do + assert_not @set.exists? + + @set.append [ 1, 2 ] + assert @set.exists? + end + + test "appending over limit" do + @set.append(%w[ 1 2 3 4 5 ]) + @set.append(%w[ 6 7 8 ]) + assert_equal %w[ 4 5 6 7 8 ], @set.elements + end + + test "prepending over limit" do + @set.prepend(%w[ 1 2 3 4 5 ]) + @set.prepend(%w[ 6 7 8 ]) + assert_equal %w[ 8 7 6 5 4 ], @set.elements + end + + test "appending array with duplicates" do + @set.append(%w[ 1 1 1 ]) + assert_equal %w[ 1 ], @set.elements + end + + test "prepending array with duplicates" do + @set.prepend(%w[ 1 1 1 ]) + assert_equal %w[ 1 ], @set.elements + end + + test "limit can't be 0 or less" do + assert_raises do + Kredis.ordered_set "ordered-set", limit: -1 + end + end +end From c1ce18270e17dd94c31f2bd964c397dbcd07ebc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Barri=C3=A9?= Date: Sun, 18 Jun 2023 17:36:09 +0200 Subject: [PATCH 18/21] Add `last` to lists (#97) * Add last to lists For simplicity, this does not strictly respect Array#last when nil or false is passed, returning the last element instead of raising a TypeError. It also doesn't coerce the parameter into an int with to_int like Array#last does. * Update list.rb Drop defensive programming * Update list_test.rb Drop defensive tests --------- Co-authored-by: David Heinemeier Hansson --- lib/kredis/types/list.rb | 4 ++++ test/types/list_test.rb | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/kredis/types/list.rb b/lib/kredis/types/list.rb index 9d54cb2..3987bfa 100644 --- a/lib/kredis/types/list.rb +++ b/lib/kredis/types/list.rb @@ -24,4 +24,8 @@ def append(*elements) def clear del end + + def last(n = nil) + n ? lrange(-n, -1) : lrange(-1, -1).first + end end diff --git a/test/types/list_test.rb b/test/types/list_test.rb index 551c50c..92cd1e2 100644 --- a/test/types/list_test.rb +++ b/test/types/list_test.rb @@ -41,6 +41,16 @@ class ListTest < ActiveSupport::TestCase assert_equal [], @list.elements end + test "last" do + @list.append(%w[ 1 2 3 ]) + assert_equal "3", @list.last + end + + test "last(n)" do + @list.append(%w[ 1 2 3 ]) + assert_equal %w[ 2 3 ], @list.last(2) + end + test "typed as datetime" do @list = Kredis.list "mylist", typed: :datetime From 1a96a743c47d7c864f4031f7dd6ee20b58c3af34 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 18 Jun 2023 17:48:10 +0200 Subject: [PATCH 19/21] Revert "Improved version of UniqueList: OrderedSet (#76)" (#111) This reverts commit a0062d18118d284a59366e6ffc5f1cb5aa2f250c. --- README.md | 8 --- lib/kredis/types.rb | 5 -- lib/kredis/types/ordered_set.rb | 71 ----------------------- test/types/ordered_set_test.rb | 99 --------------------------------- 4 files changed, 183 deletions(-) delete mode 100644 lib/kredis/types/ordered_set.rb delete mode 100644 test/types/ordered_set_test.rb diff --git a/README.md b/README.md index c9b444b..bc99d86 100644 --- a/README.md +++ b/README.md @@ -62,14 +62,6 @@ unique_list << "5" # => LREM myuniquelist 0, "5" + R unique_list.remove(3) # => LREM myuniquelist 0, "3" [ "4", "2", "1", "5" ] == unique_list.elements # => LRANGE myuniquelist 0, -1 -ordered_set = Kredis.ordered_set "myorderedset" -ordered_set.append(%w[ 2 3 4 ]) # => ZADD myorderedset 1646131025.4953232 2 1646131025.495326 3 1646131025.4953272 4 -ordered_set.prepend(%w[ 1 2 3 4 ]) # => ZADD myorderedset -1646131025.4957051 1 -1646131025.495707 2 -1646131025.4957082 3 -1646131025.4957092 4 -ordered_set.append([]) -ordered_set << "5" # => ZADD myorderedset 1646131025.4960442 5 -ordered_set.remove(3) # => ZREM myorderedset 3 -[ "4", "2", "1", "5" ] == ordered_set.elements # => ZRANGE myorderedset 0 -1 - set = Kredis.set "myset", typed: :datetime set.add(DateTime.tomorrow, DateTime.yesterday) # => SADD myset "2021-02-03 00:00:00 +0100" "2021-02-01 00:00:00 +0100" set << DateTime.tomorrow # => SADD myset "2021-02-03 00:00:00 +0100" diff --git a/lib/kredis/types.rb b/lib/kredis/types.rb index 5338a0c..16ad906 100644 --- a/lib/kredis/types.rb +++ b/lib/kredis/types.rb @@ -71,10 +71,6 @@ def set(key, typed: :string, config: :shared, after_change: nil) type_from(Set, config, key, after_change: after_change, typed: typed) end - def ordered_set(key, typed: :string, limit: nil, config: :shared, after_change: nil) - type_from(OrderedSet, config, key, after_change: after_change, typed: typed, limit: limit) - end - def slot(key, config: :shared, after_change: nil) type_from(Slots, config, key, after_change: after_change, available: 1) end @@ -103,5 +99,4 @@ def type_from(type_klass, config, key, after_change: nil, **options) require "kredis/types/list" require "kredis/types/unique_list" require "kredis/types/set" -require "kredis/types/ordered_set" require "kredis/types/slots" diff --git a/lib/kredis/types/ordered_set.rb b/lib/kredis/types/ordered_set.rb deleted file mode 100644 index 27276ab..0000000 --- a/lib/kredis/types/ordered_set.rb +++ /dev/null @@ -1,71 +0,0 @@ -class Kredis::Types::OrderedSet < Kredis::Types::Proxying - proxying :multi, :zrange, :zrem, :zadd, :zremrangebyrank, :zcard, :exists?, :del - - attr_accessor :typed - attr_reader :limit - - def elements - strings_to_types(zrange(0, -1) || [], typed) - end - alias to_a elements - - def remove(*elements) - zrem(types_to_strings(elements, typed)) - end - - def prepend(elements) - insert(elements, prepending: true) - end - - def append(elements) - insert(elements) - end - alias << append - - def limit=(limit) - raise "Limit must be greater than 0" if limit && limit <= 0 - - @limit = limit - end - - private - def insert(elements, prepending: false) - elements = Array(elements) - return if elements.empty? - - elements_with_scores = types_to_strings(elements, typed).map.with_index do |element, index| - score = generate_base_score(negative: prepending) + (index / 100000) - - [ score , element ] - end - - multi do |pipeline| - pipeline.zadd(elements_with_scores) - trim(from_beginning: prepending, pipeline: pipeline) - end - end - - def generate_base_score(negative:) - current_time = process_start_time + process_uptime - - negative ? -current_time : current_time - end - - def process_start_time - @process_start_time ||= redis.time.join(".").to_f - process_uptime - end - - def process_uptime - Process.clock_gettime(Process::CLOCK_MONOTONIC) - end - - def trim(from_beginning:, pipeline:) - return unless limit - - if from_beginning - pipeline.zremrangebyrank(limit, -1) - else - pipeline.zremrangebyrank(0, -(limit + 1)) - end - end -end diff --git a/test/types/ordered_set_test.rb b/test/types/ordered_set_test.rb deleted file mode 100644 index 420736e..0000000 --- a/test/types/ordered_set_test.rb +++ /dev/null @@ -1,99 +0,0 @@ -require "test_helper" - -class OrderedSetTest < ActiveSupport::TestCase - setup { @set = Kredis.ordered_set "ordered-set", limit: 5 } - - test "append" do - @set.append(%w[ 1 2 3 ]) - @set.append(%w[ 1 2 3 4 ]) - assert_equal %w[ 1 2 3 4 ], @set.elements - - @set << "5" - assert_equal %w[ 1 2 3 4 5 ], @set.elements - end - - test "appending the same element re-appends it" do - @set.append(%w[ 1 2 3 ]) - @set.append(%w[ 2 ]) - assert_equal %w[ 1 3 2 ], @set.elements - end - - test "mass append maintains ordering" do - @set = Kredis.ordered_set "ordered-set" # no limit - - thousand_elements = 1000.times.map { [*"A".."Z"].sample(10).join } - @set.append(thousand_elements) - assert_equal thousand_elements, @set.elements - - thousand_elements.each { |element| @set.append(element) } - assert_equal thousand_elements, @set.elements - end - - test "prepend" do - @set.prepend(%w[ 1 2 3 ]) - @set.prepend(%w[ 1 2 3 4 ]) - assert_equal %w[ 4 3 2 1 ], @set.elements - end - - test "append nothing" do - @set.append(%w[ 1 2 3 ]) - @set.append([]) - assert_equal %w[ 1 2 3 ], @set.elements - end - - test "prepend nothing" do - @set.prepend(%w[ 1 2 3 ]) - @set.prepend([]) - assert_equal %w[ 3 2 1 ], @set.elements - end - - test "typed as integers" do - @set = Kredis.ordered_set "mylist", typed: :integer - - @set.append [ 1, 2 ] - @set << 2 - assert_equal [ 1, 2 ], @set.elements - - @set.remove(2) - assert_equal [ 1 ], @set.elements - - @set.append [ "1-a", 2 ] - - assert_equal [ 1, 2 ], @set.elements - end - - test "exists?" do - assert_not @set.exists? - - @set.append [ 1, 2 ] - assert @set.exists? - end - - test "appending over limit" do - @set.append(%w[ 1 2 3 4 5 ]) - @set.append(%w[ 6 7 8 ]) - assert_equal %w[ 4 5 6 7 8 ], @set.elements - end - - test "prepending over limit" do - @set.prepend(%w[ 1 2 3 4 5 ]) - @set.prepend(%w[ 6 7 8 ]) - assert_equal %w[ 8 7 6 5 4 ], @set.elements - end - - test "appending array with duplicates" do - @set.append(%w[ 1 1 1 ]) - assert_equal %w[ 1 ], @set.elements - end - - test "prepending array with duplicates" do - @set.prepend(%w[ 1 1 1 ]) - assert_equal %w[ 1 ], @set.elements - end - - test "limit can't be 0 or less" do - assert_raises do - Kredis.ordered_set "ordered-set", limit: -1 - end - end -end From a4a336e0b333a00936e2d44c2c1fd836e3281ffd Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 18 Jun 2023 17:40:10 +0200 Subject: [PATCH 20/21] Update nokogiri for compatibility --- Gemfile.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 72eb99d..81e4cdd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,17 +86,17 @@ GEM marcel (1.0.1) method_source (1.0.0) mini_mime (1.0.3) - mini_portile2 (2.8.0) + mini_portile2 (2.8.2) minitest (5.14.4) nio4r (2.5.7) - nokogiri (1.13.8) - mini_portile2 (~> 2.8.0) + nokogiri (1.15.2) + mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.13.8-arm64-darwin) + nokogiri (1.15.2-arm64-darwin) racc (~> 1.4) - nokogiri (1.13.8-x86_64-darwin) + nokogiri (1.15.2-x86_64-darwin) racc (~> 1.4) - racc (1.6.0) + racc (1.7.1) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) @@ -147,9 +147,9 @@ GEM zeitwerk (2.4.2) PLATFORMS - arm64-darwin-20 + arm64-darwin ruby - x86_64-darwin-20 + x86_64-darwin DEPENDENCIES byebug From a781950dd38f273d5817119bfa6c8b14d3fc201f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 18 Jun 2023 17:49:32 +0200 Subject: [PATCH 21/21] Bump version for 1.4.0 --- Gemfile.lock | 10 +++++----- lib/kredis/version.rb | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 81e4cdd..123cc0b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - kredis (1.3.0) + kredis (1.4.0) activemodel (>= 6.0.0) activesupport (>= 6.0.0) redis (>= 4.2, < 6) @@ -71,7 +71,7 @@ GEM builder (3.2.4) byebug (11.1.3) concurrent-ruby (1.1.8) - connection_pool (2.2.5) + connection_pool (2.4.1) crass (1.0.6) erubi (1.10.0) globalid (0.4.2) @@ -127,9 +127,9 @@ GEM rake (>= 0.8.7) thor (~> 1.0) rake (13.0.3) - redis (5.0.2) - redis-client (~> 0.7) - redis-client (0.7.3) + redis (5.0.6) + redis-client (>= 0.9.0) + redis-client (0.14.1) connection_pool sprockets (4.0.2) concurrent-ruby (~> 1.0) diff --git a/lib/kredis/version.rb b/lib/kredis/version.rb index ac31739..3df29d9 100644 --- a/lib/kredis/version.rb +++ b/lib/kredis/version.rb @@ -1,3 +1,3 @@ module Kredis - VERSION = "1.3.0" + VERSION = "1.4.0" end