Class: Gitlab::Redis::CrossSlot::Router

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/redis/cross_slot.rb

Constant Summary collapse

UNSUPPORTED_CMD_MAPPING =

This map contains redis-rb methods which does not map directly to a standard Redis command. It is used transform unsupported commands to standard commands to find the node key for unsupported commands.

Redis::Cluster::Command only contains details of commands which the Redis Server returns. Hence, commands like mapped_hmget and hscan_each internally will call the base command, hmget and hscan respectively.

See github.com/redis/redis-rb/blob/v4.8.0/lib/redis/cluster/command.rb

{
  # Internally, redis-rb calls the supported Redis command and transforms the output.
  # See https://github.com/redis/redis-rb/blob/v4.8.0/lib/redis/commands/hashes.rb#L104
  mapped_hmget: :hmget
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redis) ⇒ Router

Initializes the CrossSlot::Router

Parameters:

  • (::Redis)


28
29
30
31
32
33
34
# File 'lib/gitlab/redis/cross_slot.rb', line 28

def initialize(redis)
  @redis = redis
  @node_mapping = {}
  @futures = {}
  @node_sequence = []
  @cmd_queue = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(cmd, *args, **kwargs, &blk) ⇒ Object

For now we intercept every redis.call and return a Gitlab-Future object. This method groups every commands to a node for fan-out. Commands are grouped using the first key.

rubocop:disable Style/MissingRespondToMissing



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/gitlab/redis/cross_slot.rb', line 40

def method_missing(cmd, *args, **kwargs, &blk)
  # Note that we can re-map the command without affecting execution as it is
  # solely for finding the node key. The original cmd will be executed.
  node = @redis._client._find_node_key([UNSUPPORTED_CMD_MAPPING.fetch(cmd, cmd)] + args)

  @node_mapping[node] ||= []
  @futures[node] ||= []

  @node_sequence << node
  @node_mapping[node] << [cmd, args, kwargs || {}, blk]
  f = Future.new
  @futures[node] << f
  @cmd_queue << [f, cmd, args, kwargs || {}, blk]
  f
end

Instance Attribute Details

#cmd_queueObject (readonly)

Returns the value of attribute cmd_queue.



7
8
9
# File 'lib/gitlab/redis/cross_slot.rb', line 7

def cmd_queue
  @cmd_queue
end

#futuresObject (readonly)

Returns the value of attribute futures.



7
8
9
# File 'lib/gitlab/redis/cross_slot.rb', line 7

def futures
  @futures
end

#node_mappingObject (readonly)

Returns the value of attribute node_mapping.



7
8
9
# File 'lib/gitlab/redis/cross_slot.rb', line 7

def node_mapping
  @node_mapping
end

#node_sequenceObject (readonly)

Returns the value of attribute node_sequence.



7
8
9
# File 'lib/gitlab/redis/cross_slot.rb', line 7

def node_sequence
  @node_sequence
end