Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active September 26, 2020 08:02
Show Gist options
  • Save tompng/eec62f4fa1f3d37f45d9eb7abcdd1226 to your computer and use it in GitHub Desktop.
Save tompng/eec62f4fa1f3d37f45d9eb7abcdd1226 to your computer and use it in GitHub Desktop.
require 'socket'
100.times.map do |t|
Thread.new do
socket = TCPSocket.new 'localhost', 9876
100.times do
key = rand 100
cmd = ["get #{key}", "set #{key} #{t}_#{rand}", "delete #{key}"].sample
socket.puts cmd
p [t, cmd, socket.gets]
end
socket.close
end
end.map(&:join)
p TCPSocket.new('localhost', 9876).then{|socket|100.times.map{|i|socket.puts("get #{i}");socket.gets.strip}.tap{socket.close}}
require "socket"
class KVSServer
def initialize(port)
@server = TCPServer.new port
@kvs_ractors = 16.times.map { run_kvs_ractor }
run_accept_loop
end
def run_kvs_ractor
Ractor.new do
hash = {}
loop do
data = Ractor.recv
pipe, (cmd, key, value) = data
case cmd
when 'get'
pipe.send hash[key]
when 'set'
prev = hash[key]
hash[key] = value
pipe.send prev
when 'delete'
hash.delete key
pipe.send :ok
end
end
end
end
def run_accept_loop
loop do
socket = @server.accept
serve socket
end
end
def serve(_socket)
Ractor.new(*@kvs_ractors) do |*kvs|
socket = Ractor.recv
ractor_for = -> key { kvs[key.hash % kvs.size] }
pipe = Ractor.new do
loop { Ractor.yield Ractor.recv }
end
while (line = socket.gets) do
cmds = line.split(' ')
case cmds
in ['get' | 'delete', key]
ractor_for[key].send [pipe, cmds], move: true
in ['set', key, String]
ractor_for[key].send [pipe, cmds], move: true
else
socket.puts "valid commands are `get [key]` `set [key] [value]` and `delete [key]`"
next
end
socket.puts pipe.take
end
ensure
socket.close
end.send _socket, move: true
end
end
KVSServer.new 9876
% telnet localhost 9876
Trying ::1...
Connected to localhost.
Escape character is '^]'.
aaaaaaa
valid commands are `get [key]` `set [key] [value]` and `delete [key]`
get foo
set foo 123
set foo 456
123
get foo
456
delete foo
ok
get foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment