Simple non-blocking web server

150 Views Asked by At

I'm trying to make a simple non-blocking web server with Perl6, but most likely I don't understand something here.

Example:

#!/usr/bin/env perl6

use v6;

react {
    whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
        whenever $conn.Supply(:bin) -> $buf {
            say "-" x 70 ~ "\n" ~ $buf.decode('UTF-8').trim-trailing;
            sleep 5; # HERE
            my $response = "HTTP/1.0 200 OK\x0D\x0A\x0D\x0A";
            $response ~= q:to/END/;
                <html>
                <head>
                    <title>Demo page</title>
                </head>
                <body>
                <h1>Title here</h1>
                <p>lorem ipsum here</p>
                </body>
                </html>
                END
            await $conn.write: $response.encode('utf-8');
            $conn.close();
        }
    }
}

Example here is almost the same as the generic sample in documentation https://docs.perl6.org/type/IO::Socket::Async

Question:

Why the page is not served as parallel but in sequential order for all clients?

1

There are 1 best solutions below

2
On BEST ANSWER

Answering for my own question here. I'm beginner of perl6 so fix me if I'm doing something strange here.

Using promises seems to fix this. I assumed previously that IO::Socket::Async would create promises for me and requests would handled in parallel by the module.

#!/usr/bin/env perl6

use v6;

my @promises;
react {
    whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
        whenever $conn.Supply(:bin) -> $buf {
            my $promise = start {
                say "-" x 70 ~ "\n" ~ $buf.decode('UTF-8').trim-trailing;
                sleep 5;
                my $response = "HTTP/1.0 200 OK\x0D\x0A\x0D\x0A";
                $response ~= q:to/END/;
                    <html>
                    <head>
                        <title>Demo page</title>
                    </head>
                    <body>
                    <h1>Title here</h1>
                    <p>lorem ipsum here</p>
                    </body>
                    </html>
                    END
                await $conn.write: $response.encode('utf-8');
                $conn.close();
            };
            push @promises, $promise;
        }
    }
}
await @promises;