Skip to content

Instantly share code, notes, and snippets.

@ixti
Last active April 3, 2020 01:55
Show Gist options
  • Save ixti/f3faeeda117a0e9f355223496d92050d to your computer and use it in GitHub Desktop.
Save ixti/f3faeeda117a0e9f355223496d92050d to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
require "net-telnet"
class Jacinto
include Enumerable
# Array(slab_id, items_count)
SLABS = /^STAT items:(\d+):number (\d+)$/
# Array(cache_key, data_bytesize, expires_in)
ITEMS = /^ITEM (.+) \[(\d+) b; (\d+) s\]$/
# @param client [Dalli::Client]
def initialize(client, timeout: 3)
@client = client
@timeout = Integer(timeout)
end
def each(&block)
return to_enum __method__ unless block_given?
each_connection do |telnet|
each_slab(telnet) do |(slab_id, items_count)|
each_item(telnet, slab_id, items_count, &block)
end
end
self
end
def inspect
"#<#{self.class}>"
end
alias to_s inspect
private
def each_slab(telnet, &block)
telnet.cmd("stats items").scan(SLABS, &block)
end
def each_item(telnet, slab_id, items_count)
telnet.cmd("stats cachedump #{slab_id} #{items_count}")
.scan(ITEMS) do |(cache_key, data_bytesize, expires_in)|
yield(cache_key, data_bytesize.to_i, expires_in.to_i)
end
end
# yields telnet connection to each server in the ring
def each_connection
@client.__send__(:ring).servers.each do |server|
begin
telnet = Net::Telnet.new({
"Host" => server.hostname,
"Port" => server.port,
"Prompt" => /(^END$)/,
"Timeout" => @timeout
})
yield telnet
rescue Errno::ECONNREFUSED => e
warn e
ensure
telnet&.close
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment