class Moneta::Server
Moneta server to be used together with Moneta::Adapters::Client @api public
Constants
- MAXSIZE
- TIMEOUT
Public Class Methods
new(store, options = {})
click to toggle source
@param [Hash] options @option options [Integer] :port (9000) TCP port @option options [String] :socket Alternative Unix socket file name
# File lib/moneta/server.rb, line 10 def initialize(store, options = {}) @store = store @server = start(options) @ios = [@server] @clients = {} @running = false end
Public Instance Methods
run()
click to toggle source
Run the server
@note This method blocks!
# File lib/moneta/server.rb, line 28 def run raise 'Already running' if @running @stop = false @running = true begin until @stop mainloop end ensure File.unlink(@socket) if @socket end end
running?()
click to toggle source
Is the server running
@return [Boolean] true if the server is running
# File lib/moneta/server.rb, line 21 def running? @running end
stop()
click to toggle source
Stop the server
# File lib/moneta/server.rb, line 42 def stop raise 'Not running' unless @running @stop = true @server.close @server = nil end
Private Instance Methods
delete_client(io)
click to toggle source
# File lib/moneta/server.rb, line 80 def delete_client(io) @ios.delete(io) @clients.delete(io) end
handle(io, buffer)
click to toggle source
# File lib/moneta/server.rb, line 90 def handle(io, buffer) buffer = @clients[io] return if buffer.bytesize < 8 # At least 4 bytes for the marshalled array size = buffer[0,4].unpack('N').first if size > MAXSIZE delete_client(io) return end return if buffer.bytesize < 4 + size buffer.slice!(0, 4) method, *args = Marshal.load(buffer.slice!(0, size)) case method when :key?, :load, :delete, :increment, :create, :features io.write(pack @store.send(method, *args)) when :store, :clear @store.send(method, *args) io.write(@nil ||= pack(nil)) else raise 'Invalid method call' end rescue IOError => ex warn "Moneta::Server - #{ex.message}" unless ex.message =~ /closed/ delete_client(io) rescue Exception => ex warn "Moneta::Server - #{ex.message}" io.write(pack Exception.new(ex.message)) end
mainloop()
click to toggle source
# File lib/moneta/server.rb, line 54 def mainloop if ios = IO.select(@ios, nil, @ios, TIMEOUT) ios[2].each do |io| io.close delete_client(io) end ios[0].each do |io| if io == @server if client = @server.accept @ios << client @clients[client] = '' end elsif io.closed? || io.eof? delete_client(io) else handle(io, @clients[io] << io.readpartial(0xFFFF)) end end end rescue SignalException => ex warn "Moneta::Server - #{ex.message}" raise if ex.signo == 15 || ex.signo == 2 # SIGTERM or SIGINT rescue Exception => ex warn "Moneta::Server - #{ex.message}" end
pack(o)
click to toggle source
# File lib/moneta/server.rb, line 85 def pack(o) s = Marshal.dump(o) [s.bytesize].pack('N') << s end
start(options)
click to toggle source
# File lib/moneta/server.rb, line 118 def start(options) if @socket = options[:socket] begin UNIXServer.open(@socket) rescue Errno::EADDRINUSE if client = (UNIXSocket.open(@socket) rescue nil) client.close raise end File.unlink(@socket) tries ||= 0 (tries += 1) < 3 ? retry : raise end else TCPServer.open(options[:host] || '127.0.0.1', options[:port] || 9000) end end