0

I'm trying to create async server in hacklang. File name is first.php:

<?hh

namespace MyExperiment;

async function server(string $host, int $port): Awaitable<void> {
    $master = stream_socket_server("tcp://$host:$port");
    stream_set_blocking($master, 0);

    while (true) {
        await stream_await($master, STREAM_AWAIT_READ, 1.0);

        $clientSocket = stream_socket_accept($master);
        stream_set_blocking($clientSocket, 0);

        handleClient($clientSocket);
    }
}

async function handleClient($socket): Awaitable<void> {
    await stream_await($socket, STREAM_AWAIT_READ, 1.0);

    $data = fread($socket, 1024);
    echo $data;

    await stream_await($socket, STREAM_AWAIT_WRITE, 1.0);

    fwrite($socket, 'aaaaaaaa');

    fclose($socket);
}

function run(): void {
    \HH\Asio\join(server('192.168.0.97', 8080));
}

run();

But this does not work. hh_client on this code says:

first.php:16:3,29: This expression is of type Awaitable, but it's either being discarded or used in a dangerous way before being awaited (Typing[4015])

first.php:20:39,47: This is why I think it is Awaitable

But I don't want to block and wait for handleClient.

Then I run code this way: hhvm -d hhvm.hack.lang.auto_typecheck=0 first.php

Server starts. But when I start to send requests to server http://192.168.0.97:8080/ from browser server blocks after few requests for very long time and does not accept new connections anymore.

Do I do something wrong? Is it possible to create server like this in hacklang at all?

$ hhvm --version
HipHop VM 3.11.0 (rel)
Compiler: tags/HHVM-3.11.0-0-g3dd564a8cde23e3205a29720d3435c771274085e
Repo schema: 52047bdda550f21c2ec2fcc295e0e6d02407be51

1 Answers1

1

But I don't want to block and wait for handleClient.

Well, if you don't await them, then there's no guarantee that they will run! Hack's async functionality lets you run different data fetching asynchronously, but you need to actually get the result out somehow. As you've written this code, HHVM makes no promises about how much of handleClient is going to run. It might be all of it, it might be none of it, it might suspend handleClient at some random await statement in the middle of it.

It's unclear what exactly you are trying to do here, but async might not be the right facility for it. Hack's async is not multithreading, and it looks like you might be trying to use it that way. Keep to PHP's one-request-one-thread model for that.

I strongly recommend you read the (recently rewritten) official documentation of async which explains what it is good for and how to use it.

Then I run code this way: hhvm -d hhvm.hack.lang.auto_typecheck=0 first.php

Don't turn off the typechecker -- it was indicating that something was wrong with your code from the get-go. :)

Josh Watzman
  • 7,060
  • 1
  • 18
  • 26
  • Thanks for answer! There should be [EventLoop](https://en.wikipedia.org/wiki/Event_loop) as bacground implementation of async/await. So when I call async function without waiting it I just expect to add new event in EventLoop and continue current function execution. I have infinite server [Coroutine](https://en.wikipedia.org/wiki/Coroutine). So I expect handleClient coroutines to be guaranteed executed. – Aleksandrlat Jan 08 '16 at 20:34
  • Maybe reason of my problem is this bug https://github.com/facebook/hhvm/issues/6500. But I don't know exactly. Maybe I'm doing something wrong. – Aleksandrlat Jan 08 '16 at 20:44
  • You are doing something wrong :) An event loop / coroutines is not quite how you want to think about async in Hack. Executing an async function does not add it to any automatic event loop. Please read the documentation I described above -- you have the wrong mental model for the way async works entirely. – Josh Watzman Jan 09 '16 at 21:37
  • "An event loop / coroutines is not quite how you want to think about async in Hack." - Why not? "Executing an async function does not add it to any automatic event loop." - Yes of course. But async function can await something, so such function becomes coroutine. When we await for example IO operation this coroutine can be added to event loop. "Please read the documentation I described above -- you have the wrong mental model for the way async works entirely." - Believe me I read not once:) This does not help to understand how it works in hack. But knowing internal implementation helps. – Aleksandrlat Jan 11 '16 at 11:56
  • I took a look at implementation. And as I understand it looks like sheduler (aka event loop) and coroutines. – Aleksandrlat Jan 11 '16 at 11:58