scala - How to handle exception with ask pattern and supervision -
how should handle exception thrown dbactor here ? i'm not sure how handle it, should pipe failure case ?
class restactor extends actor actorlogging { import context.dispatcher val dbactor = context.actorof(props[dbactor]) implicit val timeout = timeout(10 seconds) override val supervisorstrategy: supervisorstrategy = { oneforonestrategy(maxnrofretries = 10, withintimerange = 10 seconds) { case x: exception => ??? } } def receive = { case getrequest(reqctx, id) => { // perform db ask ask(dbactor, readcommand(reqctx, id)).mapto[someobject] oncomplete { case success(obj) => { // stuff } case failure(err) => err match { case x: exception => ??? } } } } }
would glad thought, in advance !
there couple of questions can see here based on ???
in code sample:
1) types of things can when override default supervisor behavior in definition of how handle exceptions? 2) when using ask, types of things can when failure result on future waiting on?
let's start first question first (usually idea). when override default supervisor strategy, gain ability change how types of unhandled exceptions in child actor handled in regards failed child actor. key word in previous sentence unhandled
. actors doing request/response, may want handle (catch) specific exceptions , return response types instead (or fail upstream future, more on later) opposed letting them go unhandled. when unhandled exception happens, lose ability respond sender description of issue , sender timeoutexception
instead future
never completed. once figured out handle explicitly, can consider rest of exceptions when defining custom supervisor strategy. inside block here:
oneforonestrategy(maxnrofretries = 10, withintimerange = 10 seconds) { case x: exception => ??? }
you chance map exception type failure directive
, defines how failure handled supervision standpoint. options are:
1) stop - stop child actor , not send more messages 2) resume - resume failed child, not restarting keeping current internal state 3) restart - similar resume, in case, old instance thrown away , new instance constructed , internal state reset (prestart) 4) escalate - escalate chain parent of supervisor
so let's given sqlexception
wanted resume , given others want restart code this:
oneforonestrategy(maxnrofretries = 10, withintimerange = 10 seconds) { case x: sqlexception => resume case other => restart }
now second question pertains when future
returns failure
response. in case, guess depends on supposed happen result of future
. if rest actor responsible completing http request (let's httpctx has complete(statuscode:int, message:string)
function on it), this:
ask(dbactor, readcommand(reqctx, id)).mapto[someobject] oncomplete { case success(obj) => reqctx.complete(200, "all good!") case failure(err:timeoutexception) => reqctx.complete(500, "request timed out") case failure(ex) => reqctx.complete(500, ex.getmessage) }
now if actor upstream responsible completing http request , needed respond actor, this:
val origin = sender ask(dbactor, readcommand(reqctx, id)).mapto[someobject] oncomplete { case success(obj) => origin ! someresponseobject case failure(ex) => origin ! status.failure(ex) }
this approach assumes in success block first want massage result object before responding. if don't want , want defer result handling sender do:
val origin = sender val fut = ask(dbactor, readcommand(reqctx, id)) fut pipeto origin
Comments
Post a Comment