Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple, stoppable Timer using Raku concurrency

I have been wrestling with Promises, Supplies and other concurrency features, but I can't get find a straightforward way to do what I want.

My goal is to do something like this:

class Timer {
    has $.promise;
    has $.counter is default(0);

    method start {
        $!promise = Promise.new;

        loop {
            $!counter++;
            self.show;
        }
    }   

    method stop {
        $!promise.break;
    }   

    method reset {
        $!counter = Nil;
        self.show;
    }

    method show {
        say "timer: $!counter";
    }   
}

my Timer $t .= new;
$t.start;
$t.stop;
$t.reset;

Of course, this doesn't work because the loop will run to infinity and we will never proceed to $t.stop.

So, please can you advise me on how to bring Raku concurrency into the picture to make this do what I would like?

like image 556
p6steve Avatar asked Jun 23 '26 07:06

p6steve


1 Answers

This would be my basic Timer class. It takes a single :display argument, which must be a Callable doing the display.

Note that the start control statement is used to start the concurrency. Inside it, there is just a loop which calls the display logic until the loop condition becomes false. Which you can do with calling the .stop method.

class Timer {
    has &.display is required;
    has Bool $!running;

    method start(Timer:D: --> Nil) {
        $!running = True;
        start {
            &!display() while $!running;
        }
    }

    method stop(Timer:D: --> Nil) {
        $!running = False;
    }
}

sub display() {
    state $count;
    print (++$count).fmt('%6d') ~ "\b" x 6;
}

my $timer = Timer.new(:&display);

$timer.start;

sleep 5;

$timer.stop;
like image 193
Elizabeth Mattijsen Avatar answered Jun 27 '26 03:06

Elizabeth Mattijsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!