Class: MudisServer

Inherits:
Object
  • Object
show all
Includes:
MudisIPCConfig
Defined in:
lib/mudis_server.rb

Overview

Socket server for handling Mudis operations via IPC mode Automatically uses UNIX sockets on Linux/macOS and TCP on Windows

Constant Summary collapse

COMMANDS =

Define command handlers mapping Each command maps to a lambda that takes a request hash and performs the corresponding Mudis operation.

{
  "read" => ->(r) { Mudis.read(r[:key], namespace: r[:namespace]) },
  "write" => ->(r) { Mudis.write(r[:key], r[:value], expires_in: r[:ttl], namespace: r[:namespace]) },
  "delete" => ->(r) { Mudis.delete(r[:key], namespace: r[:namespace]) },
  "exists" => ->(r) { Mudis.exists?(r[:key], namespace: r[:namespace]) },
  "fetch" => ->(r) { Mudis.fetch(r[:key], expires_in: r[:ttl], namespace: r[:namespace]) { r[:fallback] } },
  "inspect" => ->(r) { Mudis.inspect(r[:key], namespace: r[:namespace]) },
  "keys" => ->(r) { Mudis.keys(namespace: r[:namespace]) },
  "clear_namespace" => ->(r) { Mudis.clear_namespace(namespace: r[:namespace]) },
  "least_touched" => ->(r) { Mudis.least_touched(r[:limit]) },
  "all_keys" => ->(_) { Mudis.all_keys },
  "current_memory_bytes" => ->(_) { Mudis.current_memory_bytes },
  "max_memory_bytes" => ->(_) { Mudis.max_memory_bytes },
  "metrics" => ->(_) { Mudis.metrics }
}.freeze

Constants included from MudisIPCConfig

MudisIPCConfig::DEFAULT_RETRIES, MudisIPCConfig::DEFAULT_TIMEOUT, MudisIPCConfig::SOCKET_PATH, MudisIPCConfig::TCP_HOST, MudisIPCConfig::TCP_PORT

Class Method Summary collapse

Methods included from MudisIPCConfig

retries, timeout, use_tcp?

Class Method Details

.accept_connections(server) ⇒ Object

Accept connections in a loop (works for both TCP and UNIX)



60
61
62
63
64
65
66
67
68
69
# File 'lib/mudis_server.rb', line 60

def self.accept_connections(server)
  Thread.new do
    loop do
      client = server.accept
      Thread.new(client) do |sock|
        handle_client(sock)
      end
    end
  end
end

.handle_client(socket) ⇒ void

This method returns an undefined value.

Handle a single client connection Reads the request, processes it, and sends back the response

Parameters:

  • socket (Socket)

    The client socket (TCP or UNIX)



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mudis_server.rb', line 75

def self.handle_client(socket)
  request = JSON.parse(socket.gets, symbolize_names: true)
  return unless request

  response = process_request(request)
  write_response(socket, ok: true, value: response)
rescue StandardError => e
  write_response(socket, ok: false, error: e.message)
ensure
  socket.close
end

.process_request(req) ⇒ Object

Process a request hash and return the result Raises an error if the command is unknown

Parameters:

  • req (Hash)

    The request hash containing :cmd and other parameters

Returns:

  • (Object)

    The result of the command execution



91
92
93
94
95
96
# File 'lib/mudis_server.rb', line 91

def self.process_request(req)
  handler = COMMANDS[req[:cmd]]
  raise "Unknown command: #{req[:cmd]}" unless handler

  handler.call(req)
end

.start!Object

Start the MudisServer Automatically selects TCP on Windows, UNIX sockets elsewhere This will run in a separate thread and handle incoming client connections.



34
35
36
37
38
39
40
# File 'lib/mudis_server.rb', line 34

def self.start!
  if MudisIPCConfig.use_tcp?
    start_tcp_server!
  else
    start_unix_server!
  end
end

.start_tcp_server!Object

Start TCP server (for Windows or development)



43
44
45
46
47
48
# File 'lib/mudis_server.rb', line 43

def self.start_tcp_server!
  warn "[MudisServer] Using TCP mode - recommended for development only"
  server = TCPServer.new(TCP_HOST, TCP_PORT)
  puts "[MudisServer] Listening on TCP #{TCP_HOST}:#{TCP_PORT}"
  accept_connections(server)
end

.start_unix_server!Object

Start UNIX socket server (production mode for Linux/macOS)



51
52
53
54
55
56
57
# File 'lib/mudis_server.rb', line 51

def self.start_unix_server!
  File.unlink(SOCKET_PATH) if File.exist?(SOCKET_PATH)
  server = UNIXServer.new(SOCKET_PATH)
  server.listen(128)
  puts "[MudisServer] Listening on UNIX socket #{SOCKET_PATH}"
  accept_connections(server)
end

.write_response(socket, payload) ⇒ void

This method returns an undefined value.

Write a response to the client socket

Parameters:

  • socket (Socket)

    The client socket

  • payload (Hash)

    The response payload



102
103
104
# File 'lib/mudis_server.rb', line 102

def self.write_response(socket, payload)
  socket.puts(JSON.dump(payload))
end