Background thread, async and GUI (dlangui)

Ali Çehreli acehreli at yahoo.com
Wed Jul 6 23:17:22 UTC 2022


On 7/6/22 02:26, Bagomot wrote:

 > 1) How to make asynchronous HTTP requests with curl in order to receive
 > progress and status? And how do you know that the request is completed?

I don't know how dlangui or others automate this but I had fun writing 
the following program that uses std.concurrency and std.net.curl:

 > 3) My application must perform some work in a separate thread (I do this
 > through inheritance of the worker from core.thread.Thread, is that
 > correct?).

core.thread.Thread is low level. I would consider std.parallelism and 
std.concurrency first. (I use the latter for message passing in the 
program below.)

import std.concurrency;
import std.net.curl;
import std.conv;
import std.stdio;
import std.algorithm;
import std.range;
import std.format;

// Signifies that the main thread requests the getter to stop
// serving. (Not used here.)
struct Done {}

// Represents download progress.
struct Progress {
   size_t downloaded;
   size_t total;
}

// Represents a URL
struct Url {
   string value;
}

// The thread entry point for the getter
void getterFunc() {
   receive(
     (Done _) {
       // Not used here but this is for clean termination.
       return;
     },

     (Url url) {
       // Received a URL to get.
       auto http = HTTP(url.value);

       // std.net.curl.HTTP will call this delegate with progress
       // information...
       http.onProgress((size_t dl, size_t dln, size_t ul, size_t uln) {
         if (dl != 0) {
           // ... and we will send it along to the main thread.
           ownerTid.send(Progress(dln, dl));
         }
         return 0;
       });

       // std.net.curl.HTTP will call this delegate with
       // downloaded parts...
       http.onReceive((ubyte[] data) {
         // ... and we will send it along to the main thread.
         ownerTid.send((cast(char[])data).to!string);
         return data.length;
       });

       // Everything is set up. Let's do it.
       http.perform();
     },
   );
}

void main() {
   auto getter = spawnLinked(&getterFunc);

   getter.send(Url("dlang.org"));

   string result;
   bool done = false;
   while (!done) {
     receive(
       (LinkTerminated msg) {
         // (This may or may not be expected.)
         stderr.writefln!"The getter thread terminated.";
         done = true;
       },

       (Progress progress) {
         writeln(progress);
         if (!result.empty &&
             (progress.downloaded == progress.total)) {
           done = true;
         }
       },

       (string part) {
         result ~= part;
       },
     );
   }

   writefln!"Downloaded %s bytes:\n%s"(result.length, result);
}

Ali



More information about the Digitalmars-d-learn mailing list