On 6/12/20 3:02 PM, adnan338 wrote:

> So there are multiple "download finished" message producers, and one
> consumer of those messages. Furthermore, that producer has a callback
> that triggers an UI object.

That's almost exactly what I do in some of my programs. I use std.concurrency and the following is a working sketch of what I do.

I assumed you get finer individual granularity of progress as opposed to the binary 0% -> 100%.

import std.stdio;
import std.concurrency;
import std.algorithm;
import std.range;
import std.exception;
import std.format;
import core.thread;

struct Progress {
  Tid tid;          // The id of the reporting thread
  size_t amount;    // The amount of progress so far
  size_t total;     // Total progress (can be file size)
}

void display(Progress[Tid] progresses) {
  const amount = progresses.byValue.map!(p => p.amount).sum;
  const total = progresses.byValue.map!(p => p.total).sum;
  writefln!"%6.2f%%"(100.0 * amount / total);
}

// The worker thread function
void download(string url) {
  writefln!"Worker %s downloading %s."(thisTid, url);
  enum total = 20;
  foreach (i; 0 .. total) {
    // Imitate some progress
    Thread.sleep(100.msecs);

    // Report progress to owner
    ownerTid.send(Progress(thisTid, i + 1, total));
  }
}

void main() {
  auto list = [ "dlang.org", "ddili.org" ];
  auto downloaders = list.length
                     .iota
                     .map!(i => spawnLinked(&download, list[i]))
                     .array;

  Progress[Tid] progresses;
  size_t finished = 0;

  while (finished != list.length) {
    receive(
      (LinkTerminated arg) {
        ++finished;

        // Check whether this thread is exiting prematurely
        enforce((arg.tid in progresses) &&
                (progresses[arg.tid].amount ==  progresses[arg.tid].total),
                format!"Thread %s exited unexpectedly"(arg.tid));
      },

      (Progress progress) {
        progresses[progress.tid] = progress;
        progresses.display();
      }
    );
  }

  writeln("Processing the downloaded files.");
}

Ali

Reply via email to