Class: Herdis::Shepherd::Shard

Inherits:
Object
  • Object
show all
Defined in:
lib/herdis/shepherd.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Shard

Returns a new instance of Shard.



20
21
22
23
24
25
26
# File 'lib/herdis/shepherd.rb', line 20

def initialize(options = {})
  @shepherd = options.delete(:shepherd)
  @id = options.delete(:id)
  @master = options.delete(:master)
  Dir.mkdir(dir) unless Dir.exists?(dir)
  initialize_redis
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



18
19
20
# File 'lib/herdis/shepherd.rb', line 18

def id
  @id
end

#masterObject (readonly)

Returns the value of attribute master.



19
20
21
# File 'lib/herdis/shepherd.rb', line 19

def master
  @master
end

#shepherdObject (readonly)

Returns the value of attribute shepherd.



17
18
19
# File 'lib/herdis/shepherd.rb', line 17

def shepherd
  @shepherd
end

Instance Method Details

#connectionObject



36
37
38
39
40
41
42
# File 'lib/herdis/shepherd.rb', line 36

def connection
  if master
    @connection ||= Redis.new(:host => "localhost", :port => port, :password => "slaved")
  else
    @connection ||= Redis.new(:host => "localhost", :port => port)
  end
end

#dirObject



27
28
29
# File 'lib/herdis/shepherd.rb', line 27

def dir
  File.join(shepherd.dir, "shard#{id}")
end

#enslave!(external_uri) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/herdis/shepherd.rb', line 68

def enslave!(external_uri)
  unless external_uri == master
    connection.shutdown
    @master = external_uri
    @connection = nil
    initialize_redis
    shepherd.masters.delete(id.to_s)
    shepherd.slaves[id.to_s] = self
    shepherd.save_config!
  end
end

#initialize_redisObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/herdis/shepherd.rb', line 79

def initialize_redis
  begin
    begin
      connection.shutdown          
    rescue RuntimeError => e
      if e.message == "ERR Client sent AUTH, but no password is set"
        Redis.new(:host => "localhost", :port => port).shutdown
      else
        raise e
      end
    end
  rescue Errno::ECONNREFUSED => e
  end
  io = IO.popen("#{shepherd.redis} -", "w")
  write_configuration(io)
  initialization = Proc.new do |p|
    unless master
      begin
        unless connection.get("#{self.class.name}.id")
          connection.set("#{self.class.name}.id", id) 
          connection.set("#{self.class.name}.created_at", Time.now.to_i)
          connection.set("#{self.class.name}.created_by", shepherd.shepherd_id)
        end
      rescue Errno::ECONNREFUSED => e
        EM.add_timer(0.1) do
          p.call(p)
        end
      rescue RuntimeError => e
        if e.message == "ERR operation not permitted"
          EM.add_timer(0.1) do
            p.call(p)
          end
        else
          raise e
        end
      end
    end
  end
  EM.add_timer(0.1) do
    initialization.call(initialization)
  end
end

#inmemoryObject



33
34
35
# File 'lib/herdis/shepherd.rb', line 33

def inmemory
  shepherd.inmemory
end

#inspectObject



43
44
45
46
47
48
49
# File 'lib/herdis/shepherd.rb', line 43

def inspect
  begin
    super
  rescue Errno::ECONNREFUSED => e
    "#<#{self.class.name} @dir=#{dir} @port=#{port} CLOSED>"
  end
end

#liberate!Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/herdis/shepherd.rb', line 50

def liberate!
  if master
    @master = nil
    begin
      connection.slaveof("NO", "ONE")
      connection.config("set", "requirepass", "")
      shepherd.slaves.delete(id.to_s)
      shepherd.masters[id.to_s] = self
      shepherd.save_config!
    rescue RuntimeError => e
      if e.message == "LOADING Redis is loading the dataset in memory"
        EM::Synchrony.sleep(0.1)
      else
        raise e
      end
    end
  end
end

#portObject



30
31
32
# File 'lib/herdis/shepherd.rb', line 30

def port
  shepherd.first_port + id.to_i
end

#write_configuration(io) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/herdis/shepherd.rb', line 121

def write_configuration(io)
  io.puts("daemonize yes")
  io.puts("pidfile #{dir}/pid")
  io.puts("port #{port}")
  io.puts("timeout 300")
  if master
    io.puts("slaveof #{master.host} #{master.port}")
    io.puts("requirepass slaved")
  end
  unless inmemory
    io.puts("save 900 1")
    io.puts("save 300 10")
    io.puts("save 60 10000")
    io.puts("dbfilename dump.rdb")
  end
  io.puts("dir #{dir}")
  io.puts("logfile stdout")
  io.close
end