[Scala 2.5.4] Websocket dropping messages

156 views
Skip to first unread message

Jxtps

unread,
Jun 13, 2016, 7:29:16 PM6/13/16
to play-framework
Recently upgraded to 2.5.4 and started using the Actor-based sockets (WebSocket.accept { ... ActorFlow.actorRef(out => Props(...)) }). The ergonomics have certainly been improved compared to the Iteratees / Enumerators, which is great.

However, we sometimes burst 50+ messages to the client, and while the Channel used before buffered those as needed, with the Actor / Akka Streams we now need to set a specific buffer size and then an overflow strategy.

Is it possible to make Akka Streams expand the buffer on demand? The message bursts will not grow unbounded, but I don't actually know if it needs 10, 100, or 1000 slots and it feels silly to massively over allocate?

(Using the OverflowStrategy.backpressure leads to an IllegalArgumentException: requirement failed: Backpressure overflowStrategy not supported)

Also, what happens if there are a lot of client -> server messages? There doesn't seem to be a buffer size to specify for those - is there a risk of incoming messages getting dropped?

Jxtps

unread,
Jun 13, 2016, 8:21:41 PM6/13/16
to play-framework
Digging into the source code it seems like Akka allocates a fixed buffer if the size is "small enough" (n <128 || n < ActorMaterializerSettings.maxFixedBufferSize), otherwise it first allocates a fixed buffer with 128 slots, but then falls back on a linked list if the actually used size grows beyond that.

However, ActorMaterializerSettings.maxFixedBufferSize = 1000000000 by default, so a fixed size buffer of the size specified will "always" be created.

Reading the documentation, that value can be configured with akka.stream.materializer.max-fixed-buffer-size but it's used for many different streams, so it's unclear how safe it is to change that value.

I guess I'll stick with over-allocating buffers. One question still remains: is there a risk of incoming messages getting dropped?

Jxtps

unread,
Jun 14, 2016, 12:14:32 PM6/14/16
to play-framework
Filed Issue #6246 for the dropping of outgoing messages. Still unclear on incoming messages (haven't observed anything dropped in testing, but haven't tested exhaustively).

Suggested workaround if you're affected: Set the default buffer size to be ActorMaterializer.settings.maxFixedBufferSize so that a 128-slot fixed buffer is allocated, but if actual usage ever goes beyond 128 slots, then it automatically switches to a LinkedList-backed queue, never dropping messages.

Jxtps

unread,
Jun 14, 2016, 8:05:10 PM6/14/16
to play-framework
Tested the incoming messages with a simple for-loop on the client, sending 10k messages in one go and none were dropped, so incoming messages appear to be ok (have not verified by reviewing the source code - presumably the messages get sent to the receiving actor's inbox, and that one expands as needed).
Reply all
Reply to author
Forward
0 new messages