Commit aaac5a11 authored by Elvis Pranskevichus's avatar Elvis Pranskevichus

Add golang echo server

parent f9aa2e26
...@@ -7,22 +7,26 @@ RUN DEBIAN_FRONTEND=noninteractive \ ...@@ -7,22 +7,26 @@ RUN DEBIAN_FRONTEND=noninteractive \
ENV LANG en_US.UTF-8 ENV LANG en_US.UTF-8
ENV WORKON_HOME /usr/local/python-venvs ENV WORKON_HOME /usr/local/python-venvs
ENV GOMAXPROCS 1
RUN mkdir -p /usr/local/python-venvs RUN mkdir -p /usr/local/python-venvs
RUN DEBIAN_FRONTEND=noninteractive \ RUN DEBIAN_FRONTEND=noninteractive \
apt-get update && apt-get install -y \ apt-get update && apt-get install -y \
autoconf automake libtool build-essential \ autoconf automake libtool build-essential \
python3 python3-pip git nodejs gosu python3 python3-pip git nodejs golang gosu
RUN pip3 install vex RUN pip3 install vex
RUN vex --python=python3.5 -m bench pip install -U pip RUN vex --python=python3.5 -m bench pip install -U pip
RUN mkdir -p /var/lib/cache/pip RUN mkdir -p /var/lib/cache/pip
ADD servers /usr/src/servers ADD servers /usr/src/servers
RUN go build /usr/src/servers/goecho.go
RUN vex bench pip --cache-dir=/var/lib/cache/pip \ RUN vex bench pip --cache-dir=/var/lib/cache/pip \
install -r /usr/src/servers/requirements.txt install -r /usr/src/servers/requirements.txt
RUN vex bench pip freeze -r /usr/src/servers/requirements.txt
EXPOSE 25000 EXPOSE 25000
VOLUME /var/lib/cache VOLUME /var/lib/cache
......
...@@ -42,8 +42,6 @@ if __name__ == '__main__': ...@@ -42,8 +42,6 @@ if __name__ == '__main__':
help='message size in bytes') help='message size in bytes')
parser.add_argument('--duration', '-T', default=30, type=int, parser.add_argument('--duration', '-T', default=30, type=int,
help='duration of test in seconds') help='duration of test in seconds')
parser.add_argument('--times', default=1, type=int,
help='number of times to run the test')
parser.add_argument('--concurrency', default=3, type=int, parser.add_argument('--concurrency', default=3, type=int,
help='request concurrency') help='request concurrency')
parser.add_argument('--timeout', default=2, type=int, parser.add_argument('--timeout', default=2, type=int,
...@@ -75,7 +73,7 @@ if __name__ == '__main__': ...@@ -75,7 +73,7 @@ if __name__ == '__main__':
else: else:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(15) sock.settimeout(timeout / 1000)
sock.connect(addr) sock.connect(addr)
n = 0 n = 0
...@@ -102,7 +100,6 @@ if __name__ == '__main__': ...@@ -102,7 +100,6 @@ if __name__ == '__main__':
return n, latency_stats, min_latency, max_latency return n, latency_stats, min_latency, max_latency
TIMES = args.times
N = args.concurrency N = args.concurrency
DURATION = args.duration DURATION = args.duration
...@@ -111,25 +108,25 @@ if __name__ == '__main__': ...@@ -111,25 +108,25 @@ if __name__ == '__main__':
messages = 0 messages = 0
latency_stats = None latency_stats = None
start = time.monotonic() start = time.monotonic()
for _ in range(TIMES):
with futures.ProcessPoolExecutor(max_workers=N) as e: with futures.ProcessPoolExecutor(max_workers=N) as e:
fs = [] fs = []
for _ in range(N): for _ in range(N):
fs.append(e.submit(run_test, start, DURATION)) fs.append(e.submit(run_test, start, DURATION))
res = futures.wait(fs) res = futures.wait(fs)
for fut in res.done: for fut in res.done:
t_messages, t_latency_stats, t_min_latency, t_max_latency = \ t_messages, t_latency_stats, t_min_latency, t_max_latency = \
fut.result() fut.result()
messages += t_messages messages += t_messages
if latency_stats is None: if latency_stats is None:
latency_stats = t_latency_stats latency_stats = t_latency_stats
else: else:
latency_stats = np.add(latency_stats, t_latency_stats) latency_stats = np.add(latency_stats, t_latency_stats)
if t_max_latency > max_latency: if t_max_latency > max_latency:
max_latency = t_max_latency max_latency = t_max_latency
if t_min_latency < min_latency: if t_min_latency < min_latency:
min_latency = t_min_latency min_latency = t_min_latency
end = time.monotonic() end = time.monotonic()
......
...@@ -73,6 +73,12 @@ benchmarks = [{ ...@@ -73,6 +73,12 @@ benchmarks = [{
'server': nodejs + ['/usr/src/servers/nodeecho.js'], 'server': nodejs + ['/usr/src/servers/nodeecho.js'],
'server_address': tcp_address, 'server_address': tcp_address,
'client': tcp_client, 'client': tcp_client,
}, {
'name': 'tcpecho-golang',
'title': 'TCP echo server (golang)',
'server': ['/usr/src/servers/goecho'],
'server_address': tcp_address,
'client': tcp_client,
}, { }, {
'name': 'tcpecho-asyncio-streams', 'name': 'tcpecho-asyncio-streams',
'title': 'TCP echo server (asyncio/streams)', 'title': 'TCP echo server (asyncio/streams)',
......
// Taken from https://gist.github.com/paulsmith/775764#file-echo-go
package main
import (
"net"
"strconv"
"fmt"
)
const PORT = 25000
func main() {
server, err := net.Listen("tcp", ":" + strconv.Itoa(PORT))
if server == nil {
panic("couldn't start listening: " + err.Error())
}
conns := clientConns(server)
for {
go handleConn(<-conns)
}
}
func clientConns(listener net.Listener) chan net.Conn {
ch := make(chan net.Conn)
i := 0
go func() {
for {
client, err := listener.Accept()
if client == nil {
fmt.Printf("couldn't accept: " + err.Error())
continue
}
i++
fmt.Printf("%d: %v <-> %v\n", i, client.LocalAddr(), client.RemoteAddr())
ch <- client
}
}()
return ch
}
func handleConn(client net.Conn) {
buf := make([]byte, 102400)
for {
reqLen, err := client.Read(buf)
if err != nil {
break
}
if reqLen > 0 {
client.Write(buf[:reqLen])
}
}
}
uvloop curio==0.1
curio aiohttp==0.21.5
aiohttp gevent==1.1.1
httptools tornado==4.3
gevent Twisted==16.1.1
tornado httptools==0.0.4
uvloop==0.4.7
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment