Auto-expire Redis metadata key via Redis EXPIRE

This commit also removed the unnecessary Vmpooler::Janitor lib
This commit is contained in:
Scott Schneider 2015-04-07 10:26:55 -07:00
parent 2b9f66b8d2
commit f9de28236b
5 changed files with 19 additions and 127 deletions

View file

@ -11,7 +11,7 @@ module Vmpooler
require 'timeout' require 'timeout'
require 'yaml' require 'yaml'
%w( api graphite janitor logger pool_manager vsphere_helper ).each do |lib| %w( api graphite logger pool_manager vsphere_helper ).each do |lib|
begin begin
require "vmpooler/#{lib}" require "vmpooler/#{lib}"
rescue LoadError rescue LoadError

View file

@ -1,36 +0,0 @@
module Vmpooler
class Janitor
def initialize(logger, redis, data_ttl)
# Load logger library
$logger = logger
# Connect to Redis
$redis = redis
# TTL
$data_ttl = data_ttl
end
def execute!
loop do
find_stale_vms
sleep(600)
end
end
def find_stale_vms
$redis.keys('vmpooler__vm__*').each do |key|
data = $redis.hgetall(key)
if data['destroy']
lifetime = (Time.now - Time.parse(data['destroy'])) / 60 / 60
if lifetime > $data_ttl
$redis.del(key)
end
end
end
end
end
end

View file

@ -1,10 +1,8 @@
module Vmpooler module Vmpooler
class PoolManager class PoolManager
def initialize(config, pools, logger, redis, graphite=nil) def initialize(config, logger, redis, graphite=nil)
$config = config $config = config
$pools = pools
# Load logger library # Load logger library
$logger = logger $logger = logger
@ -257,6 +255,9 @@ module Vmpooler
$redis.hdel('vmpooler__active__' + pool, vm) $redis.hdel('vmpooler__active__' + pool, vm)
$redis.hset('vmpooler__vm__' + vm, 'destroy', Time.now) $redis.hset('vmpooler__vm__' + vm, 'destroy', Time.now)
# Auto-expire metadata key
$redis.expire('vmpooler__vm__' + vm, ($config[:redis]['data_ttl'].to_i * 60 * 60))
host = $vsphere[pool].find_vm(vm) || host = $vsphere[pool].find_vm(vm) ||
$vsphere[pool].find_vm_heavy(vm)[vm] $vsphere[pool].find_vm_heavy(vm)[vm]
@ -451,7 +452,7 @@ module Vmpooler
$redis.set('vmpooler__tasks__clone', 0) $redis.set('vmpooler__tasks__clone', 0)
loop do loop do
$pools.each do |pool| $config[:pools].each do |pool|
if ! $threads[pool['name']] if ! $threads[pool['name']]
check_pool(pool) check_pool(pool)
else else

View file

@ -1,71 +0,0 @@
require 'spec_helper'
describe 'Janitor' do
let(:logger) { double('logger') }
let(:redis) { double('redis') }
let(:data_ttl) { 3 } # number of hours to retain
let(:old_destroy) { '2015-01-30 11:24:30 -0700' }
let(:fut_destroy) { '3015-01-30 11:24:30 -0700' }
subject { Vmpooler::Janitor.new(logger, redis, data_ttl) }
before do
allow(redis).to receive(:hgetall).with('key1').and_return({'destroy' => old_destroy})
allow(redis).to receive(:hgetall).with('key2').and_return({'destroy' => old_destroy})
allow(redis).to receive(:hgetall).with('key3').and_return({'destroy' => Time.now.to_s})
allow(redis).to receive(:hgetall).with('key4').and_return({'destroy' => Time.now.to_s})
allow(redis).to receive(:hgetall).with('key5').and_return({'destroy' => fut_destroy})
allow(redis).to receive(:del)
end
describe '#find_stale_vms' do
context 'has stale vms' do
it 'has one key' do
allow(redis).to receive(:keys) {['key1']}
expect(redis).to receive(:del).with('key1').once
expect(redis).to receive(:hgetall).with('key1').once
expect(redis).not_to receive(:hgetall).with('key2')
subject.find_stale_vms
end
it 'has two keys' do
allow(redis).to receive(:keys) {(%w(key1 key2))}
expect(redis).to receive(:hgetall).twice
expect(redis).to receive(:del).with('key1')
expect(redis).to receive(:del).with('key2')
subject.find_stale_vms
end
it 'has 5 keys and 2 stales' do
allow(redis).to receive(:keys) {(%w(key1 key2 key3 key4 key5))}
expect(redis).to receive(:hgetall).exactly(5).times
expect(redis).to receive(:del).with('key1')
expect(redis).to receive(:del).with('key2')
expect(redis).not_to receive(:del).with('key3')
expect(redis).not_to receive(:del).with('key4')
expect(redis).not_to receive(:del).with('key5')
subject.find_stale_vms
end
end
it 'does not have stale vms' do
allow(redis).to receive(:keys).and_return(['key1'])
allow(redis).to receive(:hgetall).with('key1') {{'destroy' => Time.now.to_s}}
allow(redis).to receive(:del).with('key1')
expect(redis).not_to receive(:del).with('key1')
subject.find_stale_vms
end
end
end

View file

@ -7,7 +7,6 @@ require 'lib/vmpooler'
config = Vmpooler.config config = Vmpooler.config
redis_host = config[:redis]['server'] redis_host = config[:redis]['server']
redis_ttl = config[:redis]['data_ttl']
logger_file = config[:config]['logfile'] logger_file = config[:config]['logfile']
graphite = config[:graphite]['server'] ? config[:graphite]['server'] : nil graphite = config[:graphite]['server'] ? config[:graphite]['server'] : nil
@ -16,16 +15,15 @@ api = Thread.new {
thr.helpers.configure(config, Vmpooler.new_redis(redis_host)) thr.helpers.configure(config, Vmpooler.new_redis(redis_host))
thr.helpers.execute! thr.helpers.execute!
} }
janitor = Thread.new {
Vmpooler::Janitor.new(Vmpooler.new_logger(logger_file), Vmpooler.new_redis(redis_host), redis_ttl).execute!
}
manager = Thread.new { manager = Thread.new {
Vmpooler::PoolManager.new(config, Vmpooler::PoolManager.new(
config[:pools], config,
Vmpooler.new_logger(logger_file), Vmpooler.new_logger(logger_file),
Vmpooler.new_redis(redis_host), Vmpooler.new_redis(redis_host),
Vmpooler.new_graphite(graphite)).execute! Vmpooler.new_graphite(graphite)
).execute!
} }
[api, janitor, manager].each { |t| t.join } [api, manager].each { |t| t.join }