Thread overview
Fiber based HTTP client for load testing
Oct 01, 2020
Arun
Oct 01, 2020
ikod
Oct 01, 2020
ikod
October 01, 2020
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?

September 30, 2020
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
October 01, 2020
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

October 01, 2020
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.