Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl6 how to get specific identity of promises?

I am trying to code 3 echo servers running in promises, but I want to know which promise is doing the echoing. Is there a way to do that?

no strict;

for 0 .. 2 -> $index {
    @result[$index] = start {
        $myID = $index; 
        say "======> $myID\n";

        my $rsSocket = IO::Socket::INET.new:
            localhost => 'localhost',
            localport => 1234 + $index,
            listen    => 1;

        while $rsSocket.accept -> $rsConnection {
            say "Promise $myID accepted connection";
            while $rsConnection.recv -> $stuff {
                say "promise $myID Echoing $stuff";
                $rsConnection.print($stuff);
            }
            $rsConnection.close;
        }
    }
}

await @result;

The echo servers run ok; tested with "nc";

The problem is $myID becomes 2 after the promises are created, and there is no way for me to tell which promise is doing the current echoing. It seems that $myID is used by all the promises; is there a way to create variables that are specific to an individual promise?

like image 443
lisprogtor Avatar asked Dec 25 '22 02:12

lisprogtor


2 Answers

That's one of the thing you "lose" by going with no strict.

What you need is lexical scoping. Using my will give you a different variable each time the block ({ ... }) is entered.

If you do this:

for 0 .. 2 -> $index {
    @result[$index] = start {
        my $myID = $index; 

Then $myID will be local to the start block, and each time that block is called, it'll remember its id. So you'll get the correct ID whenever the socket receives data.

like image 80
Ven Avatar answered Jan 10 '23 18:01

Ven


You don't really need to have a $myID at all. You can just use $index in the promise because it has already been scoped to the loop block. Here's a working modification (..with strict on):

my @result = do for 0 .. 2 -> $index {
    start {
        say "======> $index\n";

        my $rsSocket = IO::Socket::INET.new:
            localhost => 'localhost',
            localport => 1234 + $index,
            listen    => 1;

        while $rsSocket.accept -> $rsConnection {
            say "Promise $index accepted connection";
            while $rsConnection.recv -> $stuff {
                say "promise $index Echoing $stuff";
                $rsConnection.print($stuff);
            }
            $rsConnection.close;
        }
    }
}

await @result;

With that taken care of I feel the urge to point out that using no strict seems very unnecessary. Not only does it leave you open to weird scope issues like these, but you gain basically nothing from doing it in your example.

Re-enabling strict on your unmodified code and fixing the two compile errors shows have only saved a total of four keystrokes -- at the expense of however many keys you used typing up your question here.

like image 31
Jarrod Funnell Avatar answered Jan 10 '23 17:01

Jarrod Funnell