diff --git a/lib/redcord.rb b/lib/redcord.rb index 9abb049..edf5020 100644 --- a/lib/redcord.rb +++ b/lib/redcord.rb @@ -1,27 +1,18 @@ # frozen_string_literal: true -# typed: strict +# typed: true require 'sorbet-runtime' module Redcord extend T::Sig - @@configuration_blks = T.let( - [], - T::Array[T.proc.params(arg0: T.untyped).void], - ) + @@configuration_blks = [] - sig { - params( - blk: T.proc.params(arg0: T.untyped).void, - ).void - } def self.configure(&blk) @@configuration_blks << blk end - sig { void } def self._after_initialize! @@configuration_blks.each do |blk| blk.call(Redcord::Base) diff --git a/lib/redcord.rbi b/lib/redcord.rbi deleted file mode 100644 index 2d216fd..0000000 --- a/lib/redcord.rbi +++ /dev/null @@ -1,78 +0,0 @@ -# typed: strong -module ModuleClassMethodsAsInstanceMethods - # Sorbet does not understand the ClassMethods modules are actually defining - # class methods. Hence this module redefines some top level class methods as - # instance methods. Sigs are copied from - # https://github.com/sorbet/sorbet/blob/f9380ec833047a834bbaca1eb3502ae96a0e4394/rbi/core/module.rbi - include Kernel - - sig do - params( - arg0: T.any(Symbol, String), - ) - .returns(T.untyped) - end - def class_variable_get(arg0); end - - sig do - params( - arg0: T.any(Symbol, String), - arg1: BasicObject, - ) - .returns(T.untyped) - end - def class_variable_set(arg0, arg1); end - - sig {returns(String)} - def name(); end -end - -module Redcord::RedisConnection::ClassMethods - include ModuleClassMethodsAsInstanceMethods -end - -module Redcord::RedisConnection::InstanceMethods - include Kernel -end - -module Redcord::Attribute::ClassMethods - include Redcord::Serializer::ClassMethods - # from inherenting T::Struct - def prop(name, type, options={}); end -end - -module Redcord::TTL::ClassMethods - include Redcord::Serializer::ClassMethods -end - -module Redcord::Actions::ClassMethods - include Kernel - include Redcord::RedisConnection::ClassMethods - include Redcord::Serializer::ClassMethods -end - -module Redcord::Actions::InstanceMethods - include Kernel - include Redcord::RedisConnection::InstanceMethods - - sig {returns(String)} - def to_json; end - - sig {returns(T::Hash[String, T.untyped])} - def serialize; end -end - -module Redcord::Base - include Redcord::Actions::InstanceMethods - extend Redcord::Serializer::ClassMethods - - mixes_in_class_methods(Redcord::TTL::ClassMethods) -end - -module Redcord::Serializer::ClassMethods - include ModuleClassMethodsAsInstanceMethods - - # from inherenting T::Struct - def from_hash(args); end - def props; end -end diff --git a/lib/redcord/actions.rb b/lib/redcord/actions.rb index d5b7877..97fc79c 100644 --- a/lib/redcord/actions.rb +++ b/lib/redcord/actions.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# typed: strict +# typed: true require 'sorbet-coerce' @@ -13,19 +13,12 @@ class InvalidAction < StandardError; end end module Redcord::Actions - extend T::Sig - extend T::Helpers - - sig { params(klass: T.class_of(T::Struct)).void } def self.included(klass) klass.extend(ClassMethods) klass.include(InstanceMethods) end module ClassMethods - extend T::Sig - - sig { returns(Integer) } def count Redcord::Base.trace( 'redcord_actions_class_methods_count', @@ -37,7 +30,6 @@ def count end end - sig { params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) } def create!(args) Redcord::Base.trace( 'redcord_actions_class_methods_create!', @@ -60,7 +52,6 @@ def create!(args) end end - sig { params(id: T.untyped).returns(T.untyped) } def find(id) Redcord::Base.trace( 'redcord_actions_class_methods_find', @@ -76,7 +67,6 @@ def find(id) end end - sig { params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) } def find_by(args) Redcord::Base.trace( 'redcord_actions_class_methods_find_by_args', @@ -86,12 +76,10 @@ def find_by(args) end end - sig { params(args: T::Hash[Symbol, T.untyped]).returns(Redcord::Relation) } def where(args) Redcord::Relation.new(T.let(self, T.untyped)).where(args) end - sig { params(id: T.untyped).returns(T::Boolean) } def destroy(id) Redcord::Base.trace( 'redcord_actions_class_methods_destroy', @@ -109,32 +97,6 @@ def destroy(id) end module InstanceMethods - extend T::Sig - extend T::Helpers - - abstract! - - sig { abstract.returns(T.nilable(ActiveSupport::TimeWithZone)) } - def created_at; end - - sig { - abstract.params( - time: ActiveSupport::TimeWithZone, - ).returns(T.nilable(ActiveSupport::TimeWithZone)) - } - def created_at=(time); end - - sig { abstract.returns(T.nilable(ActiveSupport::TimeWithZone)) } - def updated_at; end - - sig { - abstract.params( - time: ActiveSupport::TimeWithZone, - ).returns(T.nilable(ActiveSupport::TimeWithZone)) - } - def updated_at=(time); end - - sig { void } def save! Redcord::Base.trace( 'redcord_actions_instance_methods_save!', @@ -173,7 +135,6 @@ def save! end end - sig { returns(T::Boolean) } def save save! @@ -183,7 +144,6 @@ def save false end - sig { params(args: T::Hash[Symbol, T.untyped]).void } def update!(args) Redcord::Base.trace( 'redcord_actions_instance_methods_update!', @@ -215,7 +175,6 @@ def update!(args) end end - sig { params(args: T::Hash[Symbol, T.untyped]).returns(T::Boolean) } def update(args) update!(args) @@ -225,7 +184,6 @@ def update(args) false end - sig { returns(T::Boolean) } def destroy Redcord::Base.trace( 'redcord_actions_instance_methods_destroy', @@ -237,30 +195,24 @@ def destroy end end - sig { returns(String) } def instance_key "#{self.class.model_key}:id:#{T.must(id)}" end - sig { params(args: T::Hash[Symbol, T.untyped]).void } def _set_args!(args) args.each do |key, value| send(:"#{key}=", value) end end - sig { returns(T.nilable(String)) } def id instance_variable_get(:@_id) end private - sig { params(id: String).returns(String) } def id=(id) instance_variable_set(:@_id, id) end end - - mixes_in_class_methods(ClassMethods) end diff --git a/lib/redcord/attribute.rb b/lib/redcord/attribute.rb index 644fdd3..fd567f1 100644 --- a/lib/redcord/attribute.rb +++ b/lib/redcord/attribute.rb @@ -1,14 +1,11 @@ # frozen_string_literal: true -# typed: strict +# typed: ignore module Redcord class InvalidAttribute < StandardError; end end module Redcord::Attribute - extend T::Sig - extend T::Helpers - # We implicitly determine what should be a range index on Redis based on Ruby # type. RangeIndexType = T.type_alias { @@ -30,8 +27,7 @@ module Redcord::Attribute Time, ) } - - sig { params(klass: T.class_of(T::Struct)).void } + def self.included(klass) klass.extend(ClassMethods) klass.include(InstanceMethods) @@ -43,15 +39,6 @@ def self.included(klass) end module ClassMethods - extend T::Sig - - sig do - params( - name: Symbol, - type: T.untyped, # until smth better is proposed - options: T::Hash[Symbol, T.untyped], - ).void - end def attribute(name, type, options = {}) # TODO: support uniq options # TODO: validate types @@ -60,7 +47,6 @@ def attribute(name, type, options = {}) index_attribute(name, type) if options[:index] end - sig { params(attr: Symbol, type: T.any(Class, T::Types::Base)).void } def index_attribute(attr, type) if should_range_index?(type) class_variable_get(:@@range_index_attributes) << attr @@ -68,8 +54,7 @@ def index_attribute(attr, type) class_variable_get(:@@index_attributes) << attr end end - - sig { params(index_name: Symbol, attrs: T::Array[Symbol]).void } + def custom_index(index_name, attrs) attrs.each do |attr| type = props[attr][:type] @@ -87,7 +72,6 @@ def custom_index(index_name, attrs) class_variable_get(:@@custom_index_attributes)[index_name] = attrs end - sig { params(duration: T.nilable(ActiveSupport::Duration)).void } def ttl(duration) class_variable_set(:@@ttl, duration) end @@ -117,29 +101,24 @@ def shard_by_attribute(attr=nil) class_variable_set(:@@shard_by_attribute, attr) end - sig { returns(Integer) } def _script_arg_ttl class_variable_get(:@@ttl)&.to_i || -1 end - sig { returns(T::Array[Symbol]) } def _script_arg_index_attrs class_variable_get(:@@index_attributes).to_a end - sig { returns(T::Array[Symbol]) } def _script_arg_range_index_attrs class_variable_get(:@@range_index_attributes).to_a end - sig { returns(T::Hash[Symbol, T::Array]) } def _script_arg_custom_index_attrs class_variable_get(:@@custom_index_attributes) end private - sig { params(type: T.any(Class, T::Types::Base)).returns(T::Boolean) } def should_range_index?(type) # Change Ruby raw type to Sorbet type in order to call subtype_of? type = T::Types::Simple.new(type) if type.is_a?(Class) @@ -147,7 +126,6 @@ def should_range_index?(type) type.subtype_of?(RangeIndexType) end - sig { params(type: T.any(Class, T::Types::Base)).returns(T::Boolean) } def can_custom_index?(type) # Change Ruby raw type to Sorbet type in order to call subtype_of? type = T::Types::Simple.new(type) if type.is_a?(Class) @@ -156,9 +134,6 @@ def can_custom_index?(type) end module InstanceMethods - extend T::Sig - - sig { returns(T.nilable(String)) } def hash_tag attr = self.class.class_variable_get(:@@shard_by_attribute) @@ -175,6 +150,4 @@ def hash_tag "{#{tag || default_tag}}" end end - - mixes_in_class_methods(ClassMethods) end diff --git a/lib/redcord/base.rb b/lib/redcord/base.rb index 4e9db6b..912e87b 100644 --- a/lib/redcord/base.rb +++ b/lib/redcord/base.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true # -# typed: strict +# typed: false # # A Redis ORM API inspired by ActiveRecord: # - It provides atomic CRUD operations diff --git a/lib/redcord/configurations.rb b/lib/redcord/configurations.rb index 954d33d..af00ef1 100644 --- a/lib/redcord/configurations.rb +++ b/lib/redcord/configurations.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true # -# typed: strict +# typed: true # # This allows us to configure Redis connections for Redcord. Redis # connections can be set at the base level or model level. @@ -45,32 +45,19 @@ require 'redcord/tracer' module Redcord::Configurations - extend T::Sig - extend T::Helpers - - sig { params(klass: Module).void } def self.included(klass) klass.extend(ClassMethods) end module ClassMethods - extend T::Sig - - @@configurations = T.let( - Redcord::RedisConnection.merge_and_resolve_default({}), - T::Hash[String, T.untyped] - ) + @@configurations = Redcord::RedisConnection.merge_and_resolve_default({}) - sig { returns(T::Hash[String, T.untyped]) } def configurations @@configurations end - sig { params(config: T::Hash[String, T.untyped]).void } def configurations=(config) @@configurations = Redcord::RedisConnection.merge_and_resolve_default(config) end end - - mixes_in_class_methods(ClassMethods) end diff --git a/lib/redcord/logger.rb b/lib/redcord/logger.rb index 72a3350..aecf0e4 100644 --- a/lib/redcord/logger.rb +++ b/lib/redcord/logger.rb @@ -1,45 +1,30 @@ -# typed: strict +# typed: true + require 'rails' -module Redcord::Logger - extend T::Sig - extend T::Helpers - sig { params(klass: Module).void } +module Redcord::Logger def self.included(klass) klass.extend(ClassMethods) end module ClassMethods - extend T::Sig - - @@logger = T.let(nil, T.untyped) + @@logger = nil - sig { returns(T.untyped) } def logger @@logger end - sig { params(logger: T.untyped).void } def logger=(logger) @@logger = logger end end module LoggerMethods - extend T::Sig - # # Forward all the logger methods call to a module -- almost all logger # methods are missing and handled by method_missing. We use this trick to # dynamically swap loggers without reconfiguring the Redis clients. # - sig do - params( - method: Symbol, - args: T.untyped, - blk: T.nilable(T.proc.returns(T.untyped)) - ).returns(T.untyped) - end def self.method_missing(method, *args, &blk) logger = Redcord::Base.logger return if logger.nil? @@ -60,10 +45,7 @@ def self.method_missing(method, *args, &blk) # 2.5.5 :003 > Redcord::Base.redis.ping # show no logs # => "PONG" # - sig { returns(T.untyped) } def self.proxy Redcord::Logger::LoggerMethods end - - mixes_in_class_methods(ClassMethods) end diff --git a/lib/redcord/lua_script_reader.rb b/lib/redcord/lua_script_reader.rb index 942a861..80f02b5 100644 --- a/lib/redcord/lua_script_reader.rb +++ b/lib/redcord/lua_script_reader.rb @@ -1,13 +1,10 @@ # frozen_string_literal: true -# typed: strict +# typed: true require 'erb' module Redcord::LuaScriptReader - extend T::Sig - - sig { params(script_name: String).returns(String) } def self.read_lua_script(script_name) path = File.join( File.dirname(__FILE__), @@ -16,7 +13,6 @@ def self.read_lua_script(script_name) ERB.new(File.read(path)).result(binding) end - sig { params(relative_path: String).returns(String) } def self.include_lua(relative_path) path = File.join( File.dirname(__FILE__), diff --git a/lib/redcord/migration.rb b/lib/redcord/migration.rb index 27cdea7..5ff5672 100644 --- a/lib/redcord/migration.rb +++ b/lib/redcord/migration.rb @@ -6,24 +6,12 @@ class Redcord::Migration require 'redcord/migration/ttl' class Redcord::Migration - extend T::Sig - extend T::Helpers include Redcord::Migration::Index include Redcord::Migration::TTL - abstract! - - sig { returns(Redis) } attr_reader :redis - sig { params(redis: Redis).void } def initialize(redis) @redis = redis end - - sig { abstract.void } - def up; end - - sig { abstract.void } - def down; end end diff --git a/lib/redcord/migration/index.rb b/lib/redcord/migration/index.rb index 2a6be21..5b3ef31 100644 --- a/lib/redcord/migration/index.rb +++ b/lib/redcord/migration/index.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# typed: strict +# typed: false module Redcord::Migration::Index extend T::Sig diff --git a/lib/redcord/migration/ttl.rb b/lib/redcord/migration/ttl.rb index 31d64c3..a05a542 100644 --- a/lib/redcord/migration/ttl.rb +++ b/lib/redcord/migration/ttl.rb @@ -1,4 +1,4 @@ -# typed: strict +# typed: false module Redcord::Migration::TTL extend T::Sig diff --git a/lib/redcord/private_rbi/actions.rbi b/lib/redcord/private_rbi/actions.rbi new file mode 100644 index 0000000..dd9961c --- /dev/null +++ b/lib/redcord/private_rbi/actions.rbi @@ -0,0 +1,106 @@ +# typed: true +module Redcord::Actions + extend T::Sig + extend T::Helpers + + sig { params(klass: T.class_of(T::Struct)).void } + def self.included(klass) + end + + module ClassMethods + extend T::Sig + + sig { returns(Integer) } + def count + end + + sig { params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) } + def create!(args) + end + + sig { params(id: T.untyped).returns(T.untyped) } + def find(id) + end + + sig { params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) } + def find_by(args) + end + + sig { params(args: T::Hash[Symbol, T.untyped]).returns(Redcord::Relation) } + def where(args) + end + + sig { params(id: T.untyped).returns(T::Boolean) } + def destroy(id) + end + end + + module InstanceMethods + extend T::Sig + extend T::Helpers + + sig { returns(T.nilable(ActiveSupport::TimeWithZone)) } + def created_at; end + + sig { + params( + time: ActiveSupport::TimeWithZone, + ).returns(T.nilable(ActiveSupport::TimeWithZone)) + } + def created_at=(time); end + + sig { returns(T.nilable(ActiveSupport::TimeWithZone)) } + def updated_at; end + + sig { + params( + time: ActiveSupport::TimeWithZone, + ).returns(T.nilable(ActiveSupport::TimeWithZone)) + } + def updated_at=(time); end + + sig { void } + def save! + end + + sig { returns(T::Boolean) } + def save + end + + sig { params(args: T::Hash[Symbol, T.untyped]).void } + def update!(args) + end + + sig { params(args: T::Hash[Symbol, T.untyped]).returns(T::Boolean) } + def update(args) + end + + sig { returns(T::Boolean) } + def destroy + end + + sig { returns(String) } + def instance_key + end + + sig { params(args: T::Hash[Symbol, T.untyped]).void } + def _set_args!(args) + end + + sig { returns(T.nilable(String)) } + def id + end + + private + + sig { params(id: String).returns(String) } + def id=(id) + end + end +end + +module Redcord::Base + extend Redcord::Actions::ClassMethods + + include Redcord::Actions::InstanceMethods +end diff --git a/lib/redcord/private_rbi/attribute.rbi b/lib/redcord/private_rbi/attribute.rbi new file mode 100644 index 0000000..247c124 --- /dev/null +++ b/lib/redcord/private_rbi/attribute.rbi @@ -0,0 +1,74 @@ +# typed: true +module Redcord::Attribute + extend T::Sig + extend T::Helpers + + sig { params(klass: T.class_of(T::Struct)).void } + def self.included(klass) + end + + module ClassMethods + extend T::Sig + + sig do + params( + name: Symbol, + type: T.untyped, # until smth better is proposed + options: T::Hash[Symbol, T.untyped], + ).void + end + def attribute(name, type, options = {}) + end + + sig { params(index_name: Symbol, attrs: T::Array[Symbol]).void } + def custom_index(index_name, attrs) + end + + sig { params(duration: T.nilable(ActiveSupport::Duration)).void } + def ttl(duration) + end + + def shard_by_attribute(attr=nil) + end + + sig { returns(Integer) } + def _script_arg_ttl + end + + sig { returns(T::Array[Symbol]) } + def _script_arg_index_attrs + end + + sig { returns(T::Array[Symbol]) } + def _script_arg_range_index_attrs + end + + sig { returns(T::Hash[Symbol, T::Array]) } + def _script_arg_custom_index_attrs + end + + private + + sig { params(type: T.any(Class, T::Types::Base)).returns(T::Boolean) } + def should_range_index?(type) + end + + sig { params(type: T.any(Class, T::Types::Base)).returns(T::Boolean) } + def can_custom_index?(type) + end + end + + module InstanceMethods + extend T::Sig + + sig { returns(T.nilable(String)) } + def hash_tag + end + end +end + +module Redcord::Base + extend Redcord::Attribute::ClassMethods + + include Redcord::Attribute::InstanceMethods +end diff --git a/lib/redcord/private_rbi/base.rbi b/lib/redcord/private_rbi/base.rbi new file mode 100644 index 0000000..0512c26 --- /dev/null +++ b/lib/redcord/private_rbi/base.rbi @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# typed: true +module Redcord::Base + extend T::Sig + extend T::Helpers + + sig { params(klass: T.class_of(T::Struct)).void } + def self.included(klass) + end + + sig { returns(T::Array[T.class_of(Redcord::Base)]) } + def self.descendants + end +end diff --git a/lib/redcord/private_rbi/configurations.rbi b/lib/redcord/private_rbi/configurations.rbi new file mode 100644 index 0000000..4b31144 --- /dev/null +++ b/lib/redcord/private_rbi/configurations.rbi @@ -0,0 +1,27 @@ +# typed: strict +module Redcord::Configurations + sig { params(klass: Module).void } + def self.included(klass) + end + + module ClassMethods + extend T::Sig + + @@configurations = T.let( + Redcord::RedisConnection.merge_and_resolve_default({}), + T::Hash[String, T.untyped] + ) + + sig { returns(T::Hash[String, T.untyped]) } + def configurations + end + + sig { params(config: T::Hash[String, T.untyped]).void } + def configurations=(config) + end + end +end + +module Redcord::Base + extend Redcord::Configurations::ClassMethods +end diff --git a/lib/redcord/private_rbi/logger.rbi b/lib/redcord/private_rbi/logger.rbi new file mode 100644 index 0000000..fae3ac6 --- /dev/null +++ b/lib/redcord/private_rbi/logger.rbi @@ -0,0 +1,46 @@ +# typed: true + +module Redcord::Logger + extend T::Sig + extend T::Helpers + + sig { params(klass: Module).void } + def self.included(klass) + end + + module ClassMethods + extend T::Sig + + @@logger = T.let(nil, T.untyped) + + sig { returns(T.untyped) } + def logger + end + + sig { params(logger: T.untyped).void } + def logger=(logger) + end + end + + module LoggerMethods + extend T::Sig + + sig do + params( + method: Symbol, + args: T.untyped, + blk: T.nilable(T.proc.returns(T.untyped)) + ).returns(T.untyped) + end + def self.method_missing(method, *args, &blk) + end + end + + sig { returns(T.untyped) } + def self.proxy + end +end + +module Redcord::Base + extend Redcord::Logger::ClassMethods +end diff --git a/lib/redcord/private_rbi/lua_script_reader.rbi b/lib/redcord/private_rbi/lua_script_reader.rbi new file mode 100644 index 0000000..103ce5c --- /dev/null +++ b/lib/redcord/private_rbi/lua_script_reader.rbi @@ -0,0 +1,11 @@ +# typed: true + +module Redcord::LuaScriptReader + sig { params(script_name: String).returns(String) } + def self.read_lua_script(script_name) + end + + sig { params(relative_path: String).returns(String) } + def self.include_lua(relative_path) + end +end diff --git a/lib/redcord/private_rbi/migration.rbi b/lib/redcord/private_rbi/migration.rbi new file mode 100644 index 0000000..20f3c4a --- /dev/null +++ b/lib/redcord/private_rbi/migration.rbi @@ -0,0 +1,20 @@ +# typed: strict +class Redcord::Migration + include Redcord::Migration::Index + include Redcord::Migration::TTL + + abstract! + + sig { returns(Redis) } + attr_reader :redis + + sig { params(redis: Redis).void } + def initialize(redis) + end + + sig { abstract.void } + def up; end + + sig { abstract.void } + def down; end +end diff --git a/lib/redcord/private_rbi/redcord.rbi b/lib/redcord/private_rbi/redcord.rbi new file mode 100644 index 0000000..c858315 --- /dev/null +++ b/lib/redcord/private_rbi/redcord.rbi @@ -0,0 +1,19 @@ +# typed: strong +module Redcord + extend T::Sig + + @@configuration_blks = T.let( + [], + T::Array[T.proc.params(arg0: T.untyped).void], + ) + + sig { + params( + blk: T.proc.params(arg0: T.untyped).void, + ).void + } + def self.configure(&blk); end + + sig { void } + def self._after_initialize!; end +end diff --git a/lib/redcord/private_rbi/redis.rbi b/lib/redcord/private_rbi/redis.rbi new file mode 100644 index 0000000..3535d8f --- /dev/null +++ b/lib/redcord/private_rbi/redis.rbi @@ -0,0 +1,104 @@ +# typed: ignore + +class Redcord::Redis < Redis + extend T::Sig + + sig do + params( + key: T.any(String, Symbol), + args: T::Hash[T.untyped, T.untyped], + ttl: T.nilable(Integer), + index_attrs: T::Array[Symbol], + range_index_attrs: T::Array[Symbol], + custom_index_attrs: T::Hash[Symbol, T::Array], + hash_tag: T.nilable(String), + ).returns(String) + end + def create_hash_returning_id(key, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag: nil) + end + + sig do + params( + model: String, + id: String, + args: T::Hash[T.untyped, T.untyped], + ttl: T.nilable(Integer), + index_attrs: T::Array[Symbol], + range_index_attrs: T::Array[Symbol], + custom_index_attrs: T::Hash[Symbol, T::Array], + hash_tag: T.nilable(String), + ).void + end + def update_hash(model, id, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag:) + end + + sig do + params( + model: String, + id: String, + index_attrs: T::Array[Symbol], + range_index_attrs: T::Array[Symbol], + custom_index_attrs: T::Hash[Symbol, T::Array], + ).returns(Integer) + end + def delete_hash(model, id, index_attrs:, range_index_attrs:, custom_index_attrs:) + end + + sig do + params( + model: String, + query_conditions: T::Hash[T.untyped, T.untyped], + index_attrs: T::Array[Symbol], + range_index_attrs: T::Array[Symbol], + select_attrs: T::Set[Symbol], + custom_index_attrs: T::Array[Symbol], + hash_tag: T.nilable(String), + custom_index_name: T.nilable(Symbol), + ).returns(T::Hash[Integer, T::Hash[T.untyped, T.untyped]]) + end + def find_by_attr( + model, + query_conditions, + select_attrs: Set.new, + index_attrs:, + range_index_attrs:, + custom_index_attrs: Array.new, + hash_tag: nil, + custom_index_name: nil + ) + end + + sig do + params( + model: String, + query_conditions: T::Hash[T.untyped, T.untyped], + index_attrs: T::Array[Symbol], + range_index_attrs: T::Array[Symbol], + custom_index_attrs: T::Array[Symbol], + hash_tag: T.nilable(String), + custom_index_name: T.nilable(Symbol), + ).returns(Integer) + end + def find_by_attr_count( + model, + query_conditions, + index_attrs:, + range_index_attrs:, + custom_index_attrs: Array.new, + hash_tag: nil, + custom_index_name: nil + ) + end + + def scan_each_shard(key, &blk) + end + + private + + def run_script(script_name, *args) + end + + sig { params(query_conditions: T::Hash[T.untyped, T.untyped], partial_order: T::Array[Symbol]).returns(T::Array[T.untyped]) } + def flatten_with_partial_sort(query_conditions, partial_order) + end +end diff --git a/lib/redcord/private_rbi/redis_connection.rbi b/lib/redcord/private_rbi/redis_connection.rbi new file mode 100644 index 0000000..c2b8821 --- /dev/null +++ b/lib/redcord/private_rbi/redis_connection.rbi @@ -0,0 +1,78 @@ +# typed: true + +module Redcord::RedisConnection + extend T::Sig + extend T::Helpers + + @connections = T.let(nil, T.nilable(T::Hash[String, T.untyped])) + @procs_to_prepare = T.let([], T::Array[Proc]) + + sig { params(klass: T.any(Module, T.class_of(T::Struct))).void } + def self.included(klass) + end + + module ClassMethods + extend T::Sig + + sig { returns(T::Hash[Symbol, T.untyped]) } + def connection_config + end + + sig { returns(Redcord::Redis) } + def redis + end + + sig { returns(Redcord::Redis) } + def establish_connection + end + + sig { params(redis: Redis).returns(Redcord::Redis) } + def redis=(redis) + end + + # We prepare the model definition such as TTL, index, and uniq when we + # establish a Redis connection (once per connection) instead of sending the + # definitions in each Redis query. + # + # TODO: Replace this with Redcord migrations + sig { params(client: T.nilable(Redis)).returns(Redcord::Redis) } + def prepare_redis!(client = nil) + end + end + + module InstanceMethods + extend T::Sig + + sig { returns(Redcord::Redis) } + def redis + end + end + + sig { + params( + config: T::Hash[String, T.untyped], + ).returns(T::Hash[String, T.untyped]) + } + def self.merge_and_resolve_default(config) + end + + sig { returns(T::Hash[String, T.untyped]) } + def self.connections + end + + sig { returns(T::Array[Proc]) } + def self.procs_to_prepare + end +end + +module Redcord::Base + extend Redcord::RedisConnection::ClassMethods + + include Redcord::RedisConnection::InstanceMethods +end + +module Redcord + sig { void } + def self.establish_connections + end +end diff --git a/lib/redcord/private_rbi/relation.rbi b/lib/redcord/private_rbi/relation.rbi new file mode 100644 index 0000000..e2b480f --- /dev/null +++ b/lib/redcord/private_rbi/relation.rbi @@ -0,0 +1,81 @@ +# typed: true + +class Redcord::Relation + extend T::Sig + + sig { returns(T.class_of(Redcord::Base)) } + attr_reader :model + + sig { returns(T::Set[Symbol]) } + attr_reader :select_attrs + + sig { returns(T.nilable(Symbol)) } + attr_reader :custom_index_name + + sig { returns(T::Hash[Symbol, T.untyped]) } + attr_reader :regular_index_query_conditions + + sig { returns(T::Hash[Symbol, T.untyped]) } + attr_reader :custom_index_query_conditions + + sig do + params( + model: T.class_of(Redcord::Base), + regular_index_query_conditions: T::Hash[Symbol, T.untyped], + custom_index_query_conditions: T::Hash[Symbol, T.untyped], + select_attrs: T::Set[Symbol], + custom_index_name: T.nilable(Symbol) + ).void + end + def initialize( + model, + regular_index_query_conditions = {}, + custom_index_query_conditions = {}, + select_attrs = Set.new, + custom_index_name: nil + ) + end + + sig { params(args: T::Hash[Symbol, T.untyped]).returns(Redcord::Relation) } + def where(args) + end + + sig do + params( + args: T.untyped, + blk: T.nilable(T.proc.params(arg0: T.untyped).void), + ).returns(T.any(Redcord::Relation, T::Array[T.untyped])) + end + def select(*args, &blk) + end + + sig { returns(Integer) } + def count + end + + sig { params(index_name: T.nilable(Symbol)).returns(Redcord::Relation) } + def with_index(index_name) + end + + private + + sig { returns(T.nilable(String)) } + def extract_hash_tag! + end + + sig { returns(T::Array[T.untyped]) } + def execute_query + end + + sig { returns(Redcord::Redis) } + def redis + end + + sig { returns(T::Hash[Symbol, T.untyped]) } + def query_conditions + end + + sig { returns(T::Hash[Symbol, T.untyped]) } + def extract_query_conditions! + end +end diff --git a/lib/redcord/private_rbi/serializer.rbi b/lib/redcord/private_rbi/serializer.rbi new file mode 100644 index 0000000..46105dc --- /dev/null +++ b/lib/redcord/private_rbi/serializer.rbi @@ -0,0 +1,96 @@ +# typed: true +module Redcord::Serializer + extend T::Sig + + sig { params(klass: T.any(Module, T.class_of(T::Struct))).void } + def self.included(klass) + end + + module ClassMethods + TIME_TYPES = T.let(Set[Time, T.nilable(Time)], T::Set[T.untyped]) + + sig { params(attribute: Symbol, val: T.untyped).returns(T.untyped) } + def encode_attr_value(attribute, val) + end + + sig { params(attribute: Symbol, val: T.untyped).returns(T.untyped) } + def decode_attr_value(attribute, val) + end + + sig { params(attr_key: Symbol, attr_val: T.untyped).returns(T.untyped)} + def validate_types_and_encode_query(attr_key, attr_val) + end + + # Validate that attributes queried for are index attributes + # For custom index: validate that attributes are present in specified index + sig { params(attr_keys: T::Array[Symbol], custom_index_name: T.nilable(Symbol)).void} + def validate_index_attributes(attr_keys, custom_index_name: nil) + end + + # Validate exclusive ranges not used; Change all query conditions to range form; + # The position of the attribute and type of query is validated on Lua side + sig { params(query_conditions: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped])} + def validate_and_adjust_custom_index_query_conditions(query_conditions) + end + + sig { + params( + attr_val: T.untyped, + attr_type: T.any(Class, T::Types::Base), + ).void + } + def validate_range_attr_types(attr_val, attr_type) + end + + sig { + params( + attr_val: T.untyped, + attr_type: T.any(Class, T::Types::Base), + ).void + } + def validate_attr_type(attr_val, attr_type) + end + + sig { + params( + attribute: Symbol, + val: T.untyped, + ).returns([T.untyped, T.untyped]) + } + def encode_range_index_attr_val(attribute, val) + end + + sig { params(attr_key: Symbol).returns(T.any(Class, T::Types::Base)) } + def get_attr_type(attr_key) + end + + sig { + params( + redis_hash: T::Hash[T.untyped, T.untyped], + id: String, + ).returns(T.untyped) + } + def coerce_and_set_id(redis_hash, id) + end + + sig { returns(String) } + def model_key + end + + sig { + params( + args: T::Hash[T.any(String, Symbol), T.untyped], + ).returns(T::Hash[Symbol, T.untyped]) + } + def to_redis_hash(args) + end + + sig { + params( + args: T::Hash[T.untyped, T.untyped], + ).returns(T::Hash[T.untyped, T.untyped]) + } + def from_redis_hash(args) + end + end +end diff --git a/lib/redcord/private_rbi/tracer.rbi b/lib/redcord/private_rbi/tracer.rbi new file mode 100644 index 0000000..b100ff7 --- /dev/null +++ b/lib/redcord/private_rbi/tracer.rbi @@ -0,0 +1,33 @@ +# typed: true + +module Redcord::Tracer + extend T::Sig + extend T::Helpers + + sig { params(klass: Module).void } + def self.included(klass) + end + + module ClassMethods + include Kernel + + extend T::Sig + + @@tracer = T.let(nil, T.untyped) + + sig { + params( + span_name: String, + model_name: String, + tags: T::Array[String], + blk: T.proc.returns(T.untyped), + ).returns(T.untyped) + } + def trace(span_name, model_name:, tags: [], &blk) + end + + sig { params(blk: T.proc.returns(T.untyped)).void } + def tracer(&blk) + end + end +end diff --git a/lib/redcord/private_rbi/vacuum_helper.rbi b/lib/redcord/private_rbi/vacuum_helper.rbi new file mode 100644 index 0000000..b833112 --- /dev/null +++ b/lib/redcord/private_rbi/vacuum_helper.rbi @@ -0,0 +1,34 @@ +# typed: true + +module Redcord::VacuumHelper + extend T::Sig + extend T::Helpers + + sig { params(model: T.class_of(Redcord::Base)).void } + def self.vacuum(model) + end + + sig { params(model: T.class_of(Redcord::Base), index_attr: Symbol).void } + def self._vacuum_index_attribute(model, index_attr) + end + + sig { params(model: T.class_of(Redcord::Base), range_index_attr: Symbol).void } + def self._vacuum_range_index_attribute(model, range_index_attr) + end + + sig { params(model: T.class_of(Redcord::Base), index_name: Symbol).void } + def self._vacuum_custom_index(model, index_name) + end + + sig { params(model: T.class_of(Redcord::Base), set_key: String).void } + def self._remove_stale_ids_from_set(model, set_key) + end + + sig { params(model: T.class_of(Redcord::Base), sorted_set_key: String).void } + def self._remove_stale_ids_from_sorted_set(model, sorted_set_key) + end + + sig { params(model: T.class_of(Redcord::Base), hash_tag: String, index_name: Symbol).void } + def self._remove_stale_records_from_custom_index(model, hash_tag, index_name) + end +end diff --git a/lib/redcord/redis.rb b/lib/redcord/redis.rb index 4751826..fa35a5f 100644 --- a/lib/redcord/redis.rb +++ b/lib/redcord/redis.rb @@ -1,22 +1,9 @@ -# typed: true +# typed: ignore require 'digest' require 'redis' require 'securerandom' class Redcord::Redis < Redis - extend T::Sig - - sig do - params( - key: T.any(String, Symbol), - args: T::Hash[T.untyped, T.untyped], - ttl: T.nilable(Integer), - index_attrs: T::Array[Symbol], - range_index_attrs: T::Array[Symbol], - custom_index_attrs: T::Hash[Symbol, T::Array], - hash_tag: T.nilable(String), - ).returns(String) - end def create_hash_returning_id(key, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag: nil) Redcord::Base.trace( 'redcord_redis_create_hash_returning_id', @@ -38,18 +25,6 @@ def create_hash_returning_id(key, args, ttl:, index_attrs:, range_index_attrs:, end end - sig do - params( - model: String, - id: String, - args: T::Hash[T.untyped, T.untyped], - ttl: T.nilable(Integer), - index_attrs: T::Array[Symbol], - range_index_attrs: T::Array[Symbol], - custom_index_attrs: T::Hash[Symbol, T::Array], - hash_tag: T.nilable(String), - ).void - end def update_hash(model, id, args, ttl:, index_attrs:, range_index_attrs:, custom_index_attrs:, hash_tag:) Redcord::Base.trace( 'redcord_redis_update_hash', @@ -73,15 +48,6 @@ def update_hash(model, id, args, ttl:, index_attrs:, range_index_attrs:, custom_ end end - sig do - params( - model: String, - id: String, - index_attrs: T::Array[Symbol], - range_index_attrs: T::Array[Symbol], - custom_index_attrs: T::Hash[Symbol, T::Array], - ).returns(Integer) - end def delete_hash(model, id, index_attrs:, range_index_attrs:, custom_index_attrs:) Redcord::Base.trace( 'redcord_redis_delete_hash', @@ -96,18 +62,6 @@ def delete_hash(model, id, index_attrs:, range_index_attrs:, custom_index_attrs: end end - sig do - params( - model: String, - query_conditions: T::Hash[T.untyped, T.untyped], - index_attrs: T::Array[Symbol], - range_index_attrs: T::Array[Symbol], - select_attrs: T::Set[Symbol], - custom_index_attrs: T::Array[Symbol], - hash_tag: T.nilable(String), - custom_index_name: T.nilable(Symbol), - ).returns(T::Hash[Integer, T::Hash[T.untyped, T.untyped]]) - end def find_by_attr( model, query_conditions, @@ -136,17 +90,6 @@ def find_by_attr( end end - sig do - params( - model: String, - query_conditions: T::Hash[T.untyped, T.untyped], - index_attrs: T::Array[Symbol], - range_index_attrs: T::Array[Symbol], - custom_index_attrs: T::Array[Symbol], - hash_tag: T.nilable(String), - custom_index_name: T.nilable(Symbol), - ).returns(Integer) - end def find_by_attr_count( model, query_conditions, @@ -212,7 +155,6 @@ def run_script(script_name, *args) # When using custom index: On Lua side script expects query conditions sorted # in the order of appearance of attributes in specified index - sig { params(query_conditions: T::Hash[T.untyped, T.untyped], partial_order: T::Array[Symbol]).returns(T::Array[T.untyped]) } def flatten_with_partial_sort(query_conditions, partial_order) conditions = partial_order.inject([]) do |result, attr| if !query_conditions[attr].nil? diff --git a/lib/redcord/redis_connection.rb b/lib/redcord/redis_connection.rb index 0d40843..d688f23 100644 --- a/lib/redcord/redis_connection.rb +++ b/lib/redcord/redis_connection.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# typed: strict +# typed: false require 'rails' @@ -8,38 +8,28 @@ require 'redcord/redis' module Redcord::RedisConnection - extend T::Sig - extend T::Helpers - @connections = T.let(nil, T.nilable(T::Hash[String, T.untyped])) @procs_to_prepare = T.let([], T::Array[Proc]) - sig { params(klass: T.any(Module, T.class_of(T::Struct))).void } def self.included(klass) klass.extend(ClassMethods) klass.include(InstanceMethods) end module ClassMethods - extend T::Sig - - sig { returns(T::Hash[Symbol, T.untyped]) } def connection_config env_config = Redcord::Base.configurations[Rails.env] (env_config[name.underscore] || env_config['default']).symbolize_keys end - sig { returns(Redcord::Redis) } def redis Redcord::RedisConnection.connections[name.underscore] ||= prepare_redis! end - sig { returns(Redcord::Redis) } def establish_connection Redcord::RedisConnection.connections[name.underscore] = prepare_redis! end - sig { params(redis: Redis).returns(Redcord::Redis) } def redis=(redis) Redcord::RedisConnection.connections[name.underscore] = prepare_redis!(redis) @@ -50,7 +40,6 @@ def redis=(redis) # definitions in each Redis query. # # TODO: Replace this with Redcord migrations - sig { params(client: T.nilable(Redis)).returns(Redcord::Redis) } def prepare_redis!(client = nil) return client if client.is_a?(Redcord::Redis) @@ -73,17 +62,11 @@ def prepare_redis!(client = nil) module InstanceMethods extend T::Sig - sig { returns(Redcord::Redis) } def redis self.class.redis end end - sig { - params( - config: T::Hash[String, T.untyped], - ).returns(T::Hash[String, T.untyped]) - } def self.merge_and_resolve_default(config) env = Rails.env config[env] = {} unless config.include?(env) @@ -91,21 +74,16 @@ def self.merge_and_resolve_default(config) config end - sig { returns(T::Hash[String, T.untyped]) } def self.connections @connections ||= {} end - sig { returns(T::Array[Proc]) } def self.procs_to_prepare @procs_to_prepare end - - mixes_in_class_methods(ClassMethods) end module Redcord - sig { void } def self.establish_connections Redcord::Base.descendants.select(&:name).each(&:establish_connection) end diff --git a/lib/redcord/relation.rb b/lib/redcord/relation.rb index cb82141..f89dcae 100644 --- a/lib/redcord/relation.rb +++ b/lib/redcord/relation.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# typed: strict +# typed: false require 'active_support/core_ext/array' require 'active_support/core_ext/module' @@ -10,32 +10,12 @@ class InvalidQuery < StandardError; end end class Redcord::Relation - extend T::Sig - - sig { returns(T.class_of(Redcord::Base)) } attr_reader :model - - sig { returns(T::Set[Symbol]) } attr_reader :select_attrs - - sig { returns(T.nilable(Symbol)) } attr_reader :custom_index_name - - sig { returns(T::Hash[Symbol, T.untyped]) } attr_reader :regular_index_query_conditions - - sig { returns(T::Hash[Symbol, T.untyped]) } attr_reader :custom_index_query_conditions - sig do - params( - model: T.class_of(Redcord::Base), - regular_index_query_conditions: T::Hash[Symbol, T.untyped], - custom_index_query_conditions: T::Hash[Symbol, T.untyped], - select_attrs: T::Set[Symbol], - custom_index_name: T.nilable(Symbol) - ).void - end def initialize( model, regular_index_query_conditions = {}, @@ -50,7 +30,6 @@ def initialize( @custom_index_name = custom_index_name end - sig { params(args: T::Hash[Symbol, T.untyped]).returns(Redcord::Relation) } def where(args) encoded_args = args.map do |attr_key, attr_val| encoded_val = model.validate_types_and_encode_query(attr_key, attr_val) @@ -64,12 +43,6 @@ def where(args) self end - sig do - params( - args: T.untyped, - blk: T.nilable(T.proc.params(arg0: T.untyped).void), - ).returns(T.any(Redcord::Relation, T::Array[T.untyped])) - end def select(*args, &blk) Redcord::Base.trace( 'redcord_relation_select', @@ -86,7 +59,6 @@ def select(*args, &blk) end end - sig { returns(Integer) } def count model.validate_index_attributes(query_conditions.keys, custom_index_name: custom_index_name) redis.find_by_attr_count( @@ -100,7 +72,6 @@ def count ) end - sig { params(index_name: T.nilable(Symbol)).returns(Redcord::Relation) } def with_index(index_name) @custom_index_name = index_name adjusted_query_conditions = model.validate_and_adjust_custom_index_query_conditions(regular_index_query_conditions) @@ -174,7 +145,6 @@ def with_index(index_name) private - sig { returns(T.nilable(String)) } def extract_hash_tag! attr = model.shard_by_attribute return nil if attr.nil? @@ -203,7 +173,6 @@ def extract_hash_tag! end end - sig { returns(T::Array[T.untyped]) } def execute_query Redcord::Base.trace( 'redcord_relation_execute_query', @@ -243,17 +212,14 @@ def execute_query end end - sig { returns(Redcord::Redis) } def redis model.redis end - sig { returns(T::Hash[Symbol, T.untyped]) } def query_conditions custom_index_name ? custom_index_query_conditions : regular_index_query_conditions end - sig { returns(T::Hash[Symbol, T.untyped]) } def extract_query_conditions! attr = model.shard_by_attribute return query_conditions if attr.nil? diff --git a/lib/redcord/serializer.rb b/lib/redcord/serializer.rb index d3a4edd..1d405e8 100644 --- a/lib/redcord/serializer.rb +++ b/lib/redcord/serializer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# typed: strict +# typed: false require 'redcord/range_interval' @@ -15,22 +15,16 @@ class CustomIndexInvalidDesign < StandardError; end # This module defines various helper methods on Redcord for serialization # between the Ruby client and Redis server. module Redcord::Serializer - extend T::Sig - - sig { params(klass: T.any(Module, T.class_of(T::Struct))).void } def self.included(klass) klass.extend(ClassMethods) end module ClassMethods - extend T::Sig - # Redis only allows range queries on floats. To allow range queries on the # Ruby Time type, encode_attr_value and decode_attr_value will implicitly # encode and decode Time attributes to a float. TIME_TYPES = T.let(Set[Time, T.nilable(Time)], T::Set[T.untyped]) - sig { params(attribute: Symbol, val: T.untyped).returns(T.untyped) } def encode_attr_value(attribute, val) if !val.blank? && TIME_TYPES.include?(props[attribute][:type]) time_in_nano_sec = val.to_i * 1_000_000_000 @@ -43,7 +37,6 @@ def encode_attr_value(attribute, val) end end - sig { params(attribute: Symbol, val: T.untyped).returns(T.untyped) } def decode_attr_value(attribute, val) if !val.blank? && TIME_TYPES.include?(props[attribute][:type]) val = val.to_i @@ -55,7 +48,6 @@ def decode_attr_value(attribute, val) end end - sig { params(attr_key: Symbol, attr_val: T.untyped).returns(T.untyped)} def validate_types_and_encode_query(attr_key, attr_val) # Validate attribute types for index attributes attr_type = get_attr_type(attr_key) @@ -75,7 +67,6 @@ def validate_types_and_encode_query(attr_key, attr_val) # Validate that attributes queried for are index attributes # For custom index: validate that attributes are present in specified index - sig { params(attr_keys: T::Array[Symbol], custom_index_name: T.nilable(Symbol)).void} def validate_index_attributes(attr_keys, custom_index_name: nil) custom_index_attributes = class_variable_get(:@@custom_index_attributes)[custom_index_name] attr_keys.each do |attr_key| @@ -102,7 +93,6 @@ def validate_index_attributes(attr_keys, custom_index_name: nil) # Validate exclusive ranges not used; Change all query conditions to range form; # The position of the attribute and type of query is validated on Lua side - sig { params(query_conditions: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped])} def validate_and_adjust_custom_index_query_conditions(query_conditions) adjusted_query_conditions = query_conditions.clone query_conditions.each do |attr_key, condition| @@ -115,12 +105,6 @@ def validate_and_adjust_custom_index_query_conditions(query_conditions) adjusted_query_conditions end - sig { - params( - attr_val: T.untyped, - attr_type: T.any(Class, T::Types::Base), - ).void - } def validate_range_attr_types(attr_val, attr_type) # Validate attribute types for range index attributes if attr_val.is_a?(Redcord::RangeInterval) @@ -137,12 +121,6 @@ def validate_range_attr_types(attr_val, attr_type) end end - sig { - params( - attr_val: T.untyped, - attr_type: T.any(Class, T::Types::Base), - ).void - } def validate_attr_type(attr_val, attr_type) if (attr_type.is_a?(Class) && !attr_val.is_a?(attr_type)) || (attr_type.is_a?(T::Types::Base) && !attr_type.valid?(attr_val)) @@ -153,12 +131,6 @@ def validate_attr_type(attr_val, attr_type) end end - sig { - params( - attribute: Symbol, - val: T.untyped, - ).returns([T.untyped, T.untyped]) - } def encode_range_index_attr_val(attribute, val) if val.is_a?(Redcord::RangeInterval) # nil is treated as -inf and +inf. This is supported in Redis sorted @@ -180,17 +152,10 @@ def encode_range_index_attr_val(attribute, val) end end - sig { params(attr_key: Symbol).returns(T.any(Class, T::Types::Base)) } def get_attr_type(attr_key) props[attr_key][:type_object] end - sig { - params( - redis_hash: T::Hash[T.untyped, T.untyped], - id: String, - ).returns(T.untyped) - } def coerce_and_set_id(redis_hash, id) # Coerce each serialized result returned from Redis back into Model # instance @@ -199,27 +164,16 @@ def coerce_and_set_id(redis_hash, id) instance end - sig { returns(String) } def model_key "Redcord:#{name}" end - sig { - params( - args: T::Hash[T.any(String, Symbol), T.untyped], - ).returns(T::Hash[Symbol, T.untyped]) - } def to_redis_hash(args) args.map do |key, val| [key.to_sym, encode_attr_value(key.to_sym, val)] end.to_h end - sig { - params( - args: T::Hash[T.untyped, T.untyped], - ).returns(T::Hash[T.untyped, T.untyped]) - } def from_redis_hash(args) args.map { |key, val| [key, decode_attr_value(key.to_sym, val)] }.to_h end diff --git a/lib/redcord/tracer.rb b/lib/redcord/tracer.rb index a518218..caa69eb 100644 --- a/lib/redcord/tracer.rb +++ b/lib/redcord/tracer.rb @@ -3,10 +3,6 @@ # typed: strict module Redcord::Tracer - extend T::Sig - extend T::Helpers - - sig { params(klass: Module).void } def self.included(klass) klass.extend(ClassMethods) end @@ -18,14 +14,6 @@ module ClassMethods @@tracer = T.let(nil, T.untyped) - sig { - params( - span_name: String, - model_name: String, - tags: T::Array[String], - blk: T.proc.returns(T.untyped), - ).returns(T.untyped) - } def trace(span_name, model_name:, tags: [], &blk) return blk.call if @@tracer.nil? @@ -38,11 +26,8 @@ def trace(span_name, model_name:, tags: [], &blk) ) end - sig { params(blk: T.proc.returns(T.untyped)).void } def tracer(&blk) @@tracer = blk end end - - mixes_in_class_methods(ClassMethods) end diff --git a/lib/redcord/vacuum_helper.rb b/lib/redcord/vacuum_helper.rb index 7227e8b..4c716db 100644 --- a/lib/redcord/vacuum_helper.rb +++ b/lib/redcord/vacuum_helper.rb @@ -1,12 +1,8 @@ # frozen_string_literal: true -# typed: strict +# typed: false module Redcord::VacuumHelper - extend T::Sig - extend T::Helpers - - sig { params(model: T.class_of(Redcord::Base)).void } def self.vacuum(model) model.class_variable_get(:@@index_attributes).each do |index_attr| puts "Vacuuming index attribute: #{index_attr}" @@ -22,7 +18,6 @@ def self.vacuum(model) end end - sig { params(model: T.class_of(Redcord::Base), index_attr: Symbol).void } def self._vacuum_index_attribute(model, index_attr) # Scan through all index attribute values by matching on Redcord:Model:index_attr:* model.redis.scan_each_shard("#{model.model_key}:#{index_attr}:*") do |key| @@ -30,7 +25,6 @@ def self._vacuum_index_attribute(model, index_attr) end end - sig { params(model: T.class_of(Redcord::Base), range_index_attr: Symbol).void } def self._vacuum_range_index_attribute(model, range_index_attr) range_index_set_key = "#{model.model_key}:#{range_index_attr}" range_index_set_nil_key = "#{range_index_set_key}:" @@ -46,7 +40,6 @@ def self._vacuum_range_index_attribute(model, range_index_attr) end end - sig { params(model: T.class_of(Redcord::Base), index_name: Symbol).void } def self._vacuum_custom_index(model, index_name) custom_index_content_key = "#{model.model_key}:custom_index:#{index_name}_content" model.redis.scan_each_shard("#{custom_index_content_key}*") do |key| @@ -55,7 +48,6 @@ def self._vacuum_custom_index(model, index_name) end end - sig { params(model: T.class_of(Redcord::Base), set_key: String).void } def self._remove_stale_ids_from_set(model, set_key) model.redis.sscan_each(set_key) do |id| if !model.redis.exists?("#{model.model_key}:id:#{id}") @@ -64,7 +56,6 @@ def self._remove_stale_ids_from_set(model, set_key) end end - sig { params(model: T.class_of(Redcord::Base), sorted_set_key: String).void } def self._remove_stale_ids_from_sorted_set(model, sorted_set_key) model.redis.zscan_each(sorted_set_key) do |id, _| if !model.redis.exists?("#{model.model_key}:id:#{id}") @@ -73,7 +64,6 @@ def self._remove_stale_ids_from_sorted_set(model, sorted_set_key) end end - sig { params(model: T.class_of(Redcord::Base), hash_tag: String, index_name: Symbol).void } def self._remove_stale_records_from_custom_index(model, hash_tag, index_name) index_key = "#{model.model_key}:custom_index:#{index_name}#{hash_tag}" index_content_key = "#{model.model_key}:custom_index:#{index_name}_content#{hash_tag}"