1 /+ dub.sdl: 2 name "t2" 3 dflags "-I../source" 4 lflags "-lcares" 5 dependency "hio" version="*" 6 debugVersions "hioepoll" 7 debugVersions "hiosocket" 8 +/ 9 10 module tests.t2; 11 12 import std.experimental.logger; 13 import std.datetime; 14 import std.string; 15 import std.algorithm; 16 import std.range; 17 18 import core.atomic; 19 20 import hio.socket; 21 import hio.scheduler; 22 23 shared int ops; 24 25 enum client_tasks = 16; 26 enum clients = 2; 27 enum servers = 2; 28 enum duration = 15.seconds; 29 30 void client_task() 31 { 32 while(true) 33 { 34 auto s = new HioSocket(); 35 scope(exit) 36 { 37 s.close(); 38 } 39 try 40 { 41 s.connect("127.0.0.1:12345", 1.seconds); 42 if (s.connected) 43 { 44 s.send("hello".representation, 1.seconds); 45 } 46 s.close(); 47 hlSleep(100.hnsecs); 48 } 49 catch(LoopShutdownException) 50 { 51 info("got shutdown"); 52 return; 53 } 54 catch(Exception e) 55 { 56 errorf("%s", e); 57 return; 58 } 59 tracef("next iteration"); 60 } 61 } 62 63 void client_thread() 64 { 65 auto tasks = iota(client_tasks).map!(i => task(&client_task)).array; 66 tasks.each!(t => t.start()); 67 tasks.each!(t => t.wait(2*duration)); 68 } 69 70 void handler(HioSocket s) 71 { 72 scope(exit) 73 { 74 s.close(); 75 } 76 try 77 { 78 auto message = s.recv(16, 200.msecs); 79 if (!message.error && !message.timedout) 80 { 81 assert(message.input == "hello".representation, "msg: %s, sock: %s".format(message, s)); 82 } 83 } 84 catch(LoopShutdownException) 85 { 86 return; 87 } 88 catch(Exception e) 89 { 90 error("server task exception: %s", s); 91 } 92 } 93 94 void server(int so, int n) 95 { 96 auto sock = new HioSocket(so); 97 scope(exit) 98 { 99 sock.close(); 100 } 101 while(true) 102 { 103 try 104 { 105 auto client_socket = sock.accept(); 106 ops.atomicOp!"+="(1); 107 task(&handler, client_socket).start; 108 } 109 catch(LoopShutdownException) 110 { 111 return; 112 } 113 catch(Exception e) 114 { 115 errorf("server exception: %s", e); 116 return; 117 } 118 } 119 } 120 121 122 void main() 123 { 124 globalLogLevel = LogLevel.info; 125 App({ 126 auto server_socket = new HioSocket(); 127 server_socket.bind("0.0.0.0:12345"); 128 server_socket.listen(2048); 129 130 auto server_threads = iota(servers).map!(i => threaded(&server, server_socket.fileno, i).start).array; 131 132 auto client_threads = iota(clients).map!(i => threaded(&client_thread).start).array; 133 134 hlSleep(duration); 135 //globalLogLevel = LogLevel.trace; 136 client_threads.each!(t => t.shutdownThreadLoop()); 137 server_threads.each!(t => t.shutdownThreadLoop()); 138 139 client_threads.each!(t => t.wait()); 140 server_threads.each!(t => t.wait()); 141 142 server_socket.close(); 143 infof("done %d", ops); 144 }); 145 }