www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Fiber based HTTP client for load testing

reply Arun <aruncxy gmail.com> writes:
I have a REST client that can do load test of my REST services. 
It uses ikod's dlang-requests under the hood. 
https://github.com/ikod/dlang-requests

At the moment I use a thread pool to dispatch the runtime 
operation and send the requests to the server.

     /// Iterates over the enum members and builds a switch case 
statement at compile time.
     /// If the input operation matches the case, the runtime 
dispatches the corresponding
     /// task pool with it's options.
     auto pool = new TaskPool(options.threadCount);
     foreach (_; 0 .. options.threadCount) {
         foreach (__; 0 .. options.iterationCount) {
             final switch (options.operation) {
                 foreach (e; EnumMembers!Operation) {
             case e:
                     pool.put(mixin("task!" ~ e.to!string ~ 
"(options)"));
                     break;
                 }
             }
         }
     }
     pool.finish();

As seen, the downside is that the more threads we use the more 
memory the app consumes. Is there a way to replace the threads 
with fibers in this particular case so that instead of spawning 
1000 threads, we spawn 1000 fibers with just 1 thread?
Sep 30 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/30/20 8:35 PM, Arun wrote:

 As seen, the downside is that the more threads we use the more memory 
 the app consumes. Is there a way to replace the threads with fibers in 
 this particular case so that instead of spawning 1000 threads, we spawn 
 1000 fibers with just 1 thread?
 
Right on the main page, it says it can work with vibe.d. So that would be with fibers. How you create a fiber task for use in vibe.d I don't know. I've only ever used it with the web framework in mind. "just using fibers" isn't going to make it any faster. You still need an event framework to yield the fibers when they are waiting on i/o. -Steve
Sep 30 2020
prev sibling parent reply ikod <igor.khasilev gmail.com> writes:
On Thursday, 1 October 2020 at 00:35:49 UTC, Arun wrote:
 I have a REST client that can do load test of my REST services. 
 It uses ikod's dlang-requests under the hood. 
 https://github.com/ikod/dlang-requests

 At the moment I use a thread pool to dispatch the runtime 
 operation and send the requests to the server.
 As seen, the downside is that the more threads we use the more 
 memory the app consumes. Is there a way to replace the threads 
 with fibers in this particular case so that instead of spawning 
 1000 threads, we spawn 1000 fibers with just 1 thread?
Hello, you can use requests with vibe.d sockets. You'll get the idea from example: --- dub.json: { "authors": [ "me" ], "copyright": "Copyright © 2020, me", "dependencies": { "requests": "~>1.1.7", "vibe-d": "~>0.9.2" }, "description": "A minimal D application.", "license": "proprietary", "name": "t", "subConfigurations": { "requests": "vibed" } } --- import vibe.core.core; import vibe.core.log; import requests; static void workerFunc(string url) { logInfo("Param: %s", url); Request rq; rq.verbosity = 1; auto rs=rq.get(url); logInfo("response code: %s", rs.code); } void main() { auto urls = ["http://httpbin.org/", "http://httpbin.org/image"]; foreach(url; urls) { runWorkerTask(&workerFunc, url); } runApplication(); } ---
 GET / HTTP/1.1
 User-Agent: dlang-requests
 Host: httpbin.org
 Connection: Keep-Alive
 Accept-Encoding: gzip,deflate
 
 GET /image HTTP/1.1
 User-Agent: dlang-requests
 Host: httpbin.org
 Connection: Keep-Alive
 Accept-Encoding: gzip,deflate
 
< HTTP/1.1 200 OK < date: Thu, 01 Oct 2020 03:07:33 GMT < content-type: image/png < content-length: 8090 < connection: keep-alive < server: gunicorn/19.9.0 < access-control-allow-origin: * < access-control-allow-credentials: true < HTTP/1.1 200 OK < date: Thu, 01 Oct 2020 03:07:33 GMT < content-type: text/html; charset=utf-8 < content-length: 9593 < connection: keep-alive < server: gunicorn/19.9.0
 Connect time: 210 ms, 805 μs, and 9 hnsecs
 Request send time: 293 μs and 2 hnsecs
 Response recv time: 205 ms, 378 μs, and 9 hnsecs
< access-control-allow-origin: * [vibe-6(ZLjs) INF] < access-control-allow-credentials: true response code: 200
 Connect time: 210 ms, 749 μs, and 6 hnsecs
 Request send time: 307 μs and 6 hnsecs
 Response recv time: 205 ms and 922 μs
[vibe-3(cfzw) INF] response code: 200
Sep 30 2020
parent ikod <igor.khasilev gmail.com> writes:
On Thursday, 1 October 2020 at 03:10:32 UTC, ikod wrote:
 On Thursday, 1 October 2020 at 00:35:49 UTC, Arun wrote:
 I have a REST client that can do load test of my REST
 void main()
 {
     auto urls = ["http://httpbin.org/", 
 "http://httpbin.org/image"];
     foreach(url; urls)
     {
         runWorkerTask(&workerFunc, url);
Or maybe just `runTask(&workerFunc, url)` - I'm not sure which function implements fiber and not worker thread.
Sep 30 2020