Hello guys,

I’m writing a small test program to get a feeling about async programming in 
perl6. The program iterates over a lazy list of file paths and creates chained 
promises to copy, calculate hash sum and remove each file.

The problem is that sometimes the promises which return status ‘kept’ haven’t 
really deleted some of the files. It happens randomly. It happens quite often.

I’ve added a bunch of `await’, but that didn’t help.

If I write the promise in a single `start {}’ block and start and wait for each 
program the problem doesn’t appear in my tests. Only when I chain the promises.

I’d be glad to receive any help with problem or explanation about the behavior.

Sent from Mail for Windows 10

use v6;

my @errors;

my $listings = sub ($dir) {
    my @dirs = $dir.IO,;

    repeat {
        for @dirs.pop.dir -> $path {
            if $path.d {
                @dirs.push: $path;
            } else {
                take $path;
            }
        }
        CATCH {
            default {
                @errors.push: .path;
            }
        }
    } while @dirs;
};

my $lazy = gather $listings('/home/user/t');
my @procs;
my Int $count = 0;
my Int $bytes = 0;
my Int $q = 10;
my Bool $interrupted = False;
signal(SIGINT).tap({ $interrupted = True });

for $lazy.list -> $el {
    my $r = $q.rand;
    my $prom = Proc::Async.new('cp', '-L', $el, "/tmp/" ~ $el.basename ~ ".$r").
    start.
    then(-> $v {
                await $v;
                $bytes += ("/tmp/" ~ $el.basename ~ ".$r").IO.s;
                Proc::Async.new('md5sum', '-b', "/tmp/" ~ $el.basename ~ 
".$r").start;
            }).
    then(-> $v {
                await $v;
                Proc::Async.new('rm', '-f', "/tmp/" ~ $el.basename ~ 
".$r").start;
            }).then(-> $v {
                           await $v;
                       });

    push @procs: $prom;

    if @procs.elems == $q {
        await Promise.anyof(@procs);
        @procs .= grep({!$_});
        $count += $q - @procs.elems;
        last if $interrupted;
    }
}

await Promise.allof(@procs);
@procs .= grep({!$_});
$count += @procs.elems;
say "\n$count jobs and ", ($bytes/1048576).round(0.01), " mb processed";

Reply via email to