scala - Stop Akka actor on WebSocket disconnect or after idle time -
i'm using combination of akka actors, streaming , http handle scenario client tells server how receive events, , server sends client events @ rate.
here's client message server:
{ "uuid": "d30711c6-6bbf-4f11-9471-638ef7e19dfd", "starttime": "1501254050", "rate": "1.5" }
this received route looks this:
path("ws") { // /ws path allows websocket connections { extractupgradetowebsocket { upgrade => complete(upgrade.handlemessageswithsinksource(replaysink, source.maybe)) } } }
the replaysink
parses json case class, sends along supervisor actor using:
val replaysupervisor = system.actorof(replaysupervisor.props(), "replay-supervisor") val replaysink: sink[message, notused] = flow[message] .map{ case tm: textmessage.strict => val msgjson = parse(tm.getstricttext).getorelse(json.null) msgjson.as[replayrequest].getorelse("jsonparsingerror") case _ => log.error("incoming message not in proper format") } .to(sink.actorrefwithack( ref = replaysupervisor, oninitmessage = initmessage, ackmessage = ackmessage, oncompletemessage = connectionclosed ) )
the connectionclosed
message gets sent after websocket connection has timed out, since it's unbounded source otherwise.
when supervisor receives message, creates new child actor, giving uuid provided client , passes along message. or if child exists (since client has keep connection open regularly sending same event, or because changed start-time/rate , sends new message), passes along.
my question is, once connection closes, how tell child actor stop? sink above has no knowledge of child actor receives messages, cannot send connectionclosed message uuid supervisor forward tell child actor stop itself. sending poisonpill kill supervisor. best way can think of use set receivetimeout property of child stop after hasn't received event in while, , have client send regular messages.
is there more elegant way that'll stop actor moment connection closes, however?
when sink.actorref
materialized creates actor internally, actor sender of messages actor.
you keep map in supervisor sender actorref
initmessage
, child created sender. when connectionclosed
(or failed
on stream failure) sender same , can right child , shut down.
another option generate unique id (an uuid example) in route , provide initmessage(id)
, connectionclosed(id)
.
Comments
Post a Comment