module MeRedisHotMigrator
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.
Constants
- ZK_FALLBACK_METHODS
Public Class Methods
included(base)
click to toggle source
# 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
Public Instance Methods
hash_migration_possible?( keys )
click to toggle source
# 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 )
click to toggle source
# File lib/me_redis/me_redis_hot_migrator.rb, line 119 def key_zipping_migration_reversible?( keys ) !!zk_map_keys(keys) end
me_get( key )
click to toggle source
Calls superclass method
# File lib/me_redis/me_redis_hot_migrator.rb, line 17 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
me_mget(*keys)
click to toggle source
# File lib/me_redis/me_redis_hot_migrator.rb, line 25 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
migrate_to_hash_representation( keys )
click to toggle source
keys will exists after migrate, you need to call del(keys) directly uses hsetnx, meaning you will not overwrtite new values
# 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)
click to toggle source
——————————-KZ migration————————————
# 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 )
click to toggle source
# 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 )
click to toggle source
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 ]
# 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)
click to toggle source
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
# 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