// socket_performance_fixed.wren - Fixed socket performance test
import "socket" for Socket, SocketInstance
foreign class Host {
foreign static signalDone()
}
class SocketPerformance {
static findFreePort(startPort) {
for (port in startPort...(startPort + 100)) {
var result = SocketInstance.new()
if (result && !result[0]) {
var sock = result[1]
var bindResult = sock.bind("127.0.0.1", port)
if (bindResult && !bindResult[0]) {
sock.close()
return port
}
sock.close()
}
}
return 0
}
static runEchoTest() {
System.print("\n=== Echo Performance Test ===")
// Find a free port
var port = findFreePort(25000)
if (port == 0) {
System.print("Could not find free port")
return
}
System.print("Using port %(port)")
// Create server
var serverResult = SocketInstance.new()
if (!serverResult || serverResult[0]) {
System.print("Failed to create server")
return
}
var serverSock = serverResult[1]
// Bind and listen
var bindResult = serverSock.bind("127.0.0.1", port)
if (bindResult[0]) {
System.print("Bind failed: %(bindResult[0])")
serverSock.close()
return
}
var listenResult = serverSock.listen(10)
if (listenResult[0]) {
System.print("Listen failed: %(listenResult[0])")
serverSock.close()
return
}
var messageCount = 1000
var messageSize = 100
var message = "X" * messageSize
var serverDone = false
var serverMessages = 0
var serverBytes = 0
// Server fiber
var serverFiber = Fiber.new {
var acceptResult = serverSock.accept()
if (!acceptResult[0] && acceptResult[1]) {
var clientSock = SocketInstance.fromFd(acceptResult[1])
while (serverMessages < messageCount) {
var readResult = clientSock.read(4096)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
serverBytes = serverBytes + readResult[1].count
serverMessages = serverMessages + 1
// Echo back
clientSock.write(readResult[1])
}
if (serverMessages % 10 == 0) {
Fiber.yield()
}
}
clientSock.close()
}
serverDone = true
}
var clientDone = false
var clientMessages = 0
var clientBytes = 0
// Client fiber
var clientFiber = Fiber.new {
// Let server start
for (i in 1..10) Fiber.yield()
var connectResult = SocketInstance.connect("127.0.0.1", port)
if (connectResult[0]) {
System.print("Connect failed: %(connectResult[0])")
clientDone = true
return
}
var clientSock = connectResult[1]
var startTime = System.clock
// Send messages and read echoes
for (i in 1..messageCount) {
var writeErr = clientSock.write(message)
if (!writeErr) {
clientMessages = clientMessages + 1
// Read echo (with timeout)
var gotEcho = false
for (attempt in 1..50) {
var readResult = clientSock.read(4096)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
clientBytes = clientBytes + readResult[1].count
gotEcho = true
break
}
if (attempt % 10 == 0) Fiber.yield()
}
if (!gotEcho && i > 10) {
System.print("No echo received for message %(i)")
break
}
}
if (i % 10 == 0) Fiber.yield()
}
var elapsed = System.clock - startTime
System.print("\nClient Statistics:")
System.print(" Messages sent: %(clientMessages)")
System.print(" Bytes received: %(clientBytes)")
System.print(" Time: %(elapsed)s")
System.print(" Throughput: %(clientMessages/elapsed) msgs/sec")
System.print(" Bandwidth: %((clientBytes/elapsed/1024).floor) KB/sec")
clientSock.close()
clientDone = true
}
// Run both fibers
serverFiber.call()
clientFiber.call()
var iterations = 0
var maxIterations = 10000
while ((!serverDone || !clientDone) && iterations < maxIterations) {
if (!serverDone) serverFiber.call()
if (!clientDone) clientFiber.call()
iterations = iterations + 1
Fiber.yield()
}
System.print("\nServer Statistics:")
System.print(" Messages echoed: %(serverMessages)")
System.print(" Bytes processed: %(serverBytes)")
System.print(" Event loop iterations: %(iterations)")
serverSock.close()
}
static runConcurrentTest() {
System.print("\n=== Concurrent Connections Test ===")
var port = findFreePort(26000)
if (port == 0) {
System.print("Could not find free port")
return
}
System.print("Using port %(port)")
var serverResult = SocketInstance.new()
if (!serverResult || serverResult[0]) return
var serverSock = serverResult[1]
serverSock.bind("127.0.0.1", port)
serverSock.listen(50)
var connectionCount = 20
var connectionsAccepted = 0
var messagesSent = 0
// Server fiber - handles all connections
var serverDone = false
var serverFiber = Fiber.new {
var handlers = []
var attempts = 0
while (connectionsAccepted < connectionCount && attempts < 2000) {
var acceptResult = serverSock.accept()
if (!acceptResult[0] && acceptResult[1]) {
connectionsAccepted = connectionsAccepted + 1
var clientSock = SocketInstance.fromFd(acceptResult[1])
// Handler for this connection
var handler = Fiber.new {
var msg = "Hello from server to connection %(connectionsAccepted)!"
clientSock.write(msg)
messagesSent = messagesSent + 1
// Read client response
for (i in 1..20) {
var readResult = clientSock.read(256)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
break
}
Fiber.yield()
}
clientSock.close()
}
handlers.add(handler)
handler.call()
}
// Process active handlers
var active = []
for (h in handlers) {
if (!h.isDone) {
h.call()
active.add(h)
}
}
handlers = active
attempts = attempts + 1
Fiber.yield()
}
serverDone = true
}
// Create client fibers
var clientFibers = []
var clientsConnected = 0
var messagesReceived = 0
var startTime = System.clock
for (i in 1..connectionCount) {
var clientId = i
var clientFiber = Fiber.new {
// Stagger connections slightly
for (j in 1..clientId) Fiber.yield()
var connectResult = SocketInstance.connect("127.0.0.1", port)
if (!connectResult[0]) {
clientsConnected = clientsConnected + 1
var sock = connectResult[1]
// Read server message
for (attempt in 1..50) {
var readResult = sock.read(256)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
messagesReceived = messagesReceived + 1
// Send response
sock.write("Client %(clientId) received: %(readResult[1])")
break
}
Fiber.yield()
}
sock.close()
}
}
clientFibers.add(clientFiber)
}
// Start all fibers
serverFiber.call()
for (cf in clientFibers) cf.call()
// Run event loop
var iterations = 0
while (iterations < 5000) {
if (!serverDone) serverFiber.call()
var active = []
for (cf in clientFibers) {
if (!cf.isDone) {
cf.call()
active.add(cf)
}
}
clientFibers = active
if (serverDone && clientFibers.count == 0) break
iterations = iterations + 1
Fiber.yield()
}
var elapsed = System.clock - startTime
System.print("\nResults:")
System.print(" Connections attempted: %(connectionCount)")
System.print(" Clients connected: %(clientsConnected)")
System.print(" Connections accepted: %(connectionsAccepted)")
System.print(" Messages sent by server: %(messagesSent)")
System.print(" Messages received by clients: %(messagesReceived)")
System.print(" Time: %(elapsed)s")
System.print(" Connection rate: %(clientsConnected/elapsed) conn/sec")
System.print(" Event loop iterations: %(iterations)")
serverSock.close()
}
static runLatencyTest() {
System.print("\n=== Latency Test (ping-pong) ===")
var port = findFreePort(27000)
if (port == 0) return
var serverResult = SocketInstance.new()
if (!serverResult || serverResult[0]) return
var serverSock = serverResult[1]
serverSock.bind("127.0.0.1", port)
serverSock.listen(1)
var pingCount = 100
var serverDone = false
// Server: respond to pings with pongs
var serverFiber = Fiber.new {
var acceptResult = serverSock.accept()
if (!acceptResult[0] && acceptResult[1]) {
var clientSock = SocketInstance.fromFd(acceptResult[1])
for (i in 1..pingCount) {
// Wait for ping
var gotPing = false
for (attempt in 1..100) {
var readResult = clientSock.read(256)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
// Send pong immediately
clientSock.write("pong")
gotPing = true
break
}
Fiber.yield()
}
if (!gotPing) break
}
clientSock.close()
}
serverDone = true
}
var clientDone = false
var latencies = []
// Client: send pings and measure round-trip time
var clientFiber = Fiber.new {
for (i in 1..10) Fiber.yield()
var connectResult = SocketInstance.connect("127.0.0.1", port)
if (connectResult[0]) {
clientDone = true
return
}
var clientSock = connectResult[1]
for (i in 1..pingCount) {
var pingStart = System.clock
// Send ping
clientSock.write("ping")
// Wait for pong
var gotPong = false
for (attempt in 1..100) {
var readResult = clientSock.read(256)
if (!readResult[0] && readResult[1] && readResult[1].count > 0) {
var latency = (System.clock - pingStart) * 1000 // Convert to ms
latencies.add(latency)
gotPong = true
break
}
Fiber.yield()
}
if (!gotPong) break
}
clientSock.close()
clientDone = true
}
// Run test
serverFiber.call()
clientFiber.call()
while (!serverDone || !clientDone) {
if (!serverDone) serverFiber.call()
if (!clientDone) clientFiber.call()
Fiber.yield()
}
// Calculate statistics
if (latencies.count > 0) {
var sum = 0
var min = latencies[0]
var max = latencies[0]
for (lat in latencies) {
sum = sum + lat
if (lat < min) min = lat
if (lat > max) max = lat
}
var avg = sum / latencies.count
System.print("\nLatency Statistics (%(latencies.count) samples):")
System.print(" Average: %(avg) ms")
System.print(" Min: %(min) ms")
System.print(" Max: %(max) ms")
System.print(" Ping rate: %(1000/avg) pings/sec possible")
}
serverSock.close()
}
}
var mainFiber = Fiber.new {
System.print("=== Socket Performance Test Suite ===")
System.print("With fiber performance: 2.6M yields/sec (0.38μs/yield)")
SocketPerformance.runEchoTest()
SocketPerformance.runConcurrentTest()
SocketPerformance.runLatencyTest()
System.print("\n=== All Tests Complete ===")
Host.signalDone()
while(true) { Fiber.yield() }
}