Last active
September 26, 2020 08:02
-
-
Save tompng/eec62f4fa1f3d37f45d9eb7abcdd1226 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% 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