Class: Emissary::Agent::Mysql::Helper

Inherits:
Object
  • Object
show all
Defined in:
lib/emissary/agent/mysql.rb

Constant Summary collapse

DEFAULT_TIMEOUT =
30
@@class_monitor =
Monitor.new
@@locked_M =
Mutex.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#timeoutObject

Returns the value of attribute timeout.



131
132
133
# File 'lib/emissary/agent/mysql.rb', line 131

def timeout
  @timeout
end

Class Method Details

.new(host, user, password, timeout = nil) ⇒ Object

only return one locker per host+user combination



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/emissary/agent/mysql.rb', line 88

def self.new(host, user, password, timeout = nil)
  @@class_monitor.synchronize do
    (@@lockers||={})["#{host}:#{user}"] ||= begin
        allocate.instance_eval(<<-EOS, __FILE__, __LINE__)
          initialize(host, user, password, timeout || DEFAULT_TIMEOUT)
          self
        EOS
    end
    @@lockers["#{host}:#{user}"].timeout = timeout unless timeout.nil?
    @@lockers["#{host}:#{user}"]
  end
end

Instance Method Details

#connected?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/emissary/agent/mysql.rb', line 133

def connected?
  !!@connection
end

#get_binlog_infoObject

Returns [file, position]



186
187
188
189
190
191
# File 'lib/emissary/agent/mysql.rb', line 186

def get_binlog_info
  raise "get_binlog_info must be called from within a lock." unless locked?
  (result = connection.query("SHOW MASTER STATUS")).fetch_row[0,2]
ensure
  result.free unless result.nil?
end

#kill_watcher_thread!Object



213
214
215
216
# File 'lib/emissary/agent/mysql.rb', line 213

def kill_watcher_thread!
  @watcher.kill unless not @watcher.is_a?(Thread) or not @watcher.alive?
  @watcher = nil
end

#lock!Object



150
151
152
153
154
155
156
157
# File 'lib/emissary/agent/mysql.rb', line 150

def lock!
  unless locked?
    kill_watcher_thread! # make sure we have a new thread for watching
    locked_M.synchronize { @locked = true }
    connection.query("FLUSH TABLES WITH READ LOCK")
    spawn_lockwatch_thread!
  end
end

#locked?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/emissary/agent/mysql.rb', line 146

def locked?
  !!@locked
end

#locked_MObject



102
# File 'lib/emissary/agent/mysql.rb', line 102

def locked_M() @@locked_M; end

#spawn_lockwatch_thread!Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/emissary/agent/mysql.rb', line 193

def spawn_lockwatch_thread!
  if @watcher.is_a?(Thread) and not @watcher.alive?
    puts "Watcher is dead - restarting"
    @watcher = nil
  end
  
  @watcher ||= Thread.new {
    begin
      puts "Entering Watcher Loop"
      Timeout.timeout(@timeout) do
        loop { break unless locked? }
      end
    rescue Timeout::Error
    ensure
      unlock!
      Thread.exit
    end
  }
end

#unlock!Object



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/emissary/agent/mysql.rb', line 159

def unlock!
  begin
    unless not locked?
      locked_M.synchronize {
        connection.query("UNLOCK TABLES")
        @locked = false
      }
    end
  ensure
    kill_watcher_thread!
    disconnect
  end
end

#valid?Boolean

Test whether our login info is valid by attempting a database connection.

Returns:

  • (Boolean)


175
176
177
178
179
180
181
182
183
# File 'lib/emissary/agent/mysql.rb', line 175

def valid?
  begin
    !!connection
  rescue => e
    false			# Don't throw an exception, just return false.
  ensure 
    disconnect if connected? 
  end
end

#with_lockObject

Acquire a lock and, with that lock, run a block/closure.



138
139
140
141
142
143
144
# File 'lib/emissary/agent/mysql.rb', line 138

def with_lock
  begin
    lock! && yield
  ensure
    unlock!
  end
end