Module: MeRedisHotMigrator
- Defined in:
- lib/me_redis/me_redis_hot_migrator.rb
Overview
We need only to fallback getters, when you are setting new value it will go in a new place already me_mget doesn’t compartible with pipeline, it will raise exception when placed inside one.
Defined Under Namespace
Modules: FutureMigrator, PrependMethods
Constant Summary collapse
- ZK_FALLBACK_METHODS =
%i[mget hget hgetall get exists type getset]
Class Method Summary collapse
Instance Method Summary collapse
-
#hash_migration_possible?(keys) ⇒ Boolean
——————————-ME method migration—————————— check if migration possible, if not raises exception with a reason.
- #key_zipping_migration_reversible?(keys) ⇒ Boolean
-
#migrate_to_hash_representation(keys) ⇒ Object
keys will exists after migrate, you need to call del(keys) directly uses hsetnx, meaning you will not overwrtite new values.
-
#migrate_to_key_zipping(keys) ⇒ Object
——————————-KZ migration————————————.
- #reverse_from_hash_representation!(keys) ⇒ Object
-
#reverse_from_key_zipping!(keys) ⇒ Object
reverse migration done with same set of keys, i.e, if you migrated [ user:1, user:2 ] with migrate_to_key_zipping and want to reverse migration then use same argument [ user:1, user:2 ].
-
#zk_map_keys(keys) ⇒ Object
use only uniq keys! or zk_map_keys will fire an error! if transition is not one to one zk_map_keys would also fire an error.
Class Method Details
.included(base) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 7 def self.included(base) base::Future.prepend(FutureMigrator) base.class_eval do ZK_FALLBACK_METHODS.each do |method| alias_method "_#{method}", method end include(MeRedis) def me_get( key ) prev_future = _get( key ) unless @client.is_a?(self.class::Client) newvl = super(key) newvl.prev_future = prev_future if newvl.is_a?(self.class::Future) newvl || _get( key ) end def me_mget(*keys) #cannot run in pipeline because of fallbacks raise 'Cannot run in pipeline!!!' unless @client.is_a?(self.class::Client) me_mget_p(*keys).map(&:value) end end base.prepend( MeRedisHotMigrator::PrependMethods ) end |
Instance Method Details
#hash_migration_possible?(keys) ⇒ Boolean
——————————-ME method migration—————————— check if migration possible, if not raises exception with a reason
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 57 def hash_migration_possible?( keys ) result = keys.map{ |key| [split_key(key).each_with_index.map{|v,i| i == 0 ? zip_key(v) : v }, key] }.to_h raise ArgumentError.new( "Hash zipping is not one to one! #{result.keys} != #{keys}" ) if result.length != keys.length result.each do |sp_key, key| key_start = key.to_s.scan(/\A(.*?)(\d+)\z/).flatten[0] if sp_key[0].start_with?( key_start ) raise ArgumentError.new( "#{sp_key[0]} contains original key main part: #{key_start} Hash migration must be done with key zipping!") end end true end |
#key_zipping_migration_reversible?(keys) ⇒ Boolean
119 120 121 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 119 def key_zipping_migration_reversible?( keys ) !!zk_map_keys(keys) end |
#migrate_to_hash_representation(keys) ⇒ Object
keys will exists after migrate, you need to call del(keys) directly uses hsetnx, meaning you will not overwrtite new values
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 74 def migrate_to_hash_representation( keys ) raise StandardError.new('Cannot migrate inside pipeline.') unless @client.is_a?( self.class::Client ) raise ArgumentError.new('Migration is unavailable!') unless hash_migration_possible?( keys ) values = mget( keys ) pipelined do keys.each_with_index do |key, i| me_setnx( key, values[i] ) end end end |
#migrate_to_key_zipping(keys) ⇒ Object
——————————-KZ migration————————————
97 98 99 100 101 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 97 def migrate_to_key_zipping(keys) pipelined do zk_map_keys(keys).each{|new_key, key| renamenx( key, new_key )} end end |
#reverse_from_hash_representation!(keys) ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 86 def reverse_from_hash_representation!( keys ) raise "Cannot migrate inside pipeline" unless @client.is_a?(self.class::Client ) values = me_mget( keys ) pipelined do keys.each_with_index{|key, i| set( key, values[i] ) } end end |
#reverse_from_key_zipping!(keys) ⇒ Object
reverse migration done with same set of keys, i.e, if you migrated [ user:1, user:2 ] with migrate_to_key_zipping and want to reverse migration then use same argument [ user:1, user:2 ]
106 107 108 109 110 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 106 def reverse_from_key_zipping!( keys ) pipelined do zk_map_keys(keys).each{|new_key, key| rename( new_key, key ) } end end |
#zk_map_keys(keys) ⇒ Object
use only uniq keys! or zk_map_keys will fire an error! if transition is not one to one zk_map_keys would also fire an error
114 115 116 117 |
# File 'lib/me_redis/me_redis_hot_migrator.rb', line 114 def zk_map_keys(keys) keys.map{ |key| [zip_key(key), key] }.to_h .tap{ |result| raise ArgumentError.new( "Key zipping is not one to one! #{result.keys} != #{keys}" ) if result.length != keys.length } end |