New experimental feature: ServerSocket reference

1,325 views
Skip to first unread message

Anders Johnsen

unread,
May 21, 2014, 10:27:00 AM5/21/14
to General Dart Discussion
Hi all,

With the release of Dart 1.4, we've added a new experimental feature to dart:io, ServerSocket references.

A ServerSocket reference can be acquired from a ServerSocket and can be transferred to other isolates. From this reference, it's possibly to create a clone of the original ServerSocket, that will share the native socket. This makes it possible to accept incoming connection on multiple isolates, on the same network interface.

Currently, there are a few important notes about this new feature.
- It is VERY experimental, and is most likely to have its API changed.
- It is only implemented on Linux for now. There is no technical limitation to porting it to other platforms, but we want to get the API right before finalizing the implementation.

Example:

A very simple HTTP server could look like this:

  void listen(HttpServer server) {
    server.listen((HttpRequest request) {
      request.response.write("Hello, world");
      request.response.close();
    });
  }

  void main() {
    HttpServer.bind('127.0.0.1', 8080).then(listen);
  }

This will start a HTTP server on the main isolate.

Running wrk[1] as follows

  $ wrk -H 'Host: localhost' -d 15 -c 256 -t 4 http://localhost:8080/

results in around 25,000 req/sec.

Now, using ServerSocket references, we can scale this to multiple isolates:

  void handle(reference) {
    // Create a ServerSocket from the reference.
    reference.create().then((serverSocket) {
      listen(new HttpServer.listenOn(serverSocket));
    });
  }

  void main() {
    ServerSocket.bind('127.0.0.1', 8080).then((server) {
      // Get a reference to the server socket.
      var ref = server.reference;
      for (int i = 1; i < 8; i++) {
        // Spawn isolate with 'ref' as argument.
        Isolate.spawn(handle, ref);
      }
      listen(new HttpServer.listenOn(server));
    });
  }

Here we send the reference to 7 new isolates, listening to the server-socket in a total of 8 isolates. Running the same 'wrk' command as above now gives around 200,000 req/sec.


This is an important new feature for making isolates more valuable in the context of dart:io. We hope that you will try it out and provide feedback, here or at http://dartbug.com/new, to help us evolve this API in the right direction.

Thank you!,

- Anders

Filipe Morgado

unread,
May 21, 2014, 11:31:16 AM5/21/14
to mi...@dartlang.org
Great news!

Will this feature be expanded to support transferring regular sockets and websockets?

I believe a servlets-like implementation would have an isolate (or a group of them, yeah) listening to the server socket.
For each incoming request, the receiving server isolate would parse the header and transfer/route the request socket to the servlet isolate(s).

Are there alternative approaches for multi-app servers?

Transfering websockets (preferably with exclusive ownership) would be helpful as well.

+1 !!!

Sascha Schubring

unread,
May 21, 2014, 11:32:02 AM5/21/14
to mi...@dartlang.org
Hi Thanks!
I successfully tested the patch before. I have just a little experience with dart, but so far I wonder, why the Isolete is not a Server/client application itself? It'd prefere to transform the Isolate to be capable to handle streams (streams in Dart are awesome). Would you regard this as a security violation of the "isolate"?

Greets Back, Sascha

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Sascha Schubring

unread,
May 21, 2014, 11:36:07 AM5/21/14
to mi...@dartlang.org
@Filipe
With the server reference you will create a server  on an existing socket. Incoming traffic is mapped to the isolates in a load balancing manner. you can handle Websockets but the connection of the websocket then is of course limited to the isolate process that first got it! so there is no concurrency for that stream.

Filipe Morgado

unread,
May 21, 2014, 11:47:07 AM5/21/14
to
@Sascha 

I got that.

That's why I asked "Will this feature be expanded to support transferring regular sockets and websockets?"

:P

Sascha Schubring

unread,
May 21, 2014, 12:00:00 PM5/21/14
to mi...@dartlang.org
nevermind :)


:P

Anders Johnsen

unread,
May 22, 2014, 5:12:14 AM5/22/14
to General Dart Discussion
Hi Filipe,

I would really like to see us be able to transfer Sockets and WebSockets as well. We have some thoughts on the matter, but our initial focus is on ServerSockets.

Thanks!,

- Anders



--

Anders Johnsen

unread,
May 22, 2014, 5:15:00 AM5/22/14
to General Dart Discussion
Hi Sascha,

Unless I misunderstood what you want to do, I believe ReceivePorts are what you are looking for. If two isolates negotiate two ReceivePort/SendPort pairs (one in each direction), it should provide a bi-directional communication between the isolates, using the Streams API.

Cheers,

- Anders


On Wed, May 21, 2014 at 5:32 PM, Sascha Schubring <findaif...@gmail.com> wrote:

Alex Tatumizer

unread,
May 22, 2014, 12:23:59 PM5/22/14
to mi...@dartlang.org
@Anders:

> Here we send the reference to 7 new isolates, listening to the server-socket in a total of 8 isolates. Running the same 'wrk' command as above now gives around 200,000 req/sec.

Did you benchmark it on 8-core processor? If not, how can you explain linear speedup?

Anders Johnsen

unread,
May 22, 2014, 2:17:50 PM5/22/14
to General Dart Discussion

Yes, sorry, should have mentioned that! Instead of maximizing only one core, we can now maximize x cores.

Cheers,

Anders

Sascha Schubring

unread,
May 22, 2014, 6:40:32 PM5/22/14
to mi...@dartlang.org
@Anders
my question was actually similar as Filipes referring to the socket exchange between isolates. Conceptually I thought it would be advantageous having a socket opened instead of sendports, so that each Isolate can act like a real Server and Client. Then add streams etc.
The transformation I meant earlier was a sendport to socket transformation, which of course can not be inherit from the current model (afaiu)
I think I haven't yet understood the reason for the distinction of the send/recieveports in favour of socket streams.
Still, I would also be happy about socket exchange  :)

I hope that was less confusing.


Robert Åkerblom-Andersson

unread,
Aug 24, 2014, 9:01:23 AM8/24/14
to mi...@dartlang.org
Hi Anders,

I tried this out back in May thought it was a very interesting progress.

Just now I came to think of this thread and I'm wondering what is the current status of this feature? Is it closer to fully implemented now or has it been put on hold for some other reason?

Regards, Robert 

Kevin Moore

unread,
Aug 29, 2014, 11:40:31 AM8/29/14
to mi...@dartlang.org
Robert: I'm following up w/ Anders and the server team. We'll get back to you shortly.

Robert Åkerblom-Andersson

unread,
Aug 29, 2014, 12:35:21 PM8/29/14
to mi...@dartlang.org
Hi Kevin, sounds great!

dmorilha

unread,
Nov 5, 2014, 9:26:37 AM11/5/14
to mi...@dartlang.org
Hi,

did we ever get a resolution on that? Is this feature production ready?

thanks,
Reply all
Reply to author
Forward
0 new messages