Re: [akka-user] Synchronising responses sent from parents and children

2014-08-08 Thread Konrad 'ktoso' Malawski
That also works, yes.
I was unsure if sending the client your failure was OK for you.

On 8 August 2014 at 14:16:34, Lawrence Wagerfield (lawre...@dmz.wagerfield.com) 
wrote:

Hi Konrad,

Many thanks for humouring my paranoia! Greatly appreciated.

I have since implemented another approach that I believe to provide resilience 
against such an error without the performance hit. Please could you cast your 
eyes over it? This isn't the exact code, but it captures the workflow:

// Parent code...
def supervisorStrategy =
    OneForOneStrategy(loggingEnabled = false, maxNrOfRetries = 1) {
      case _ = Restart
    }

// Child code...
override def preRestart(reason: Throwable, message: Option[Any]): Unit =
    if (!responseSent) {
        client ! reason
        context stop self
    }

On Friday, August 8, 2014 1:09:20 PM UTC+1, Konrad Malawski wrote:
Hey Lawrence,
If you're willing to sacrifice performance because someone might do something 
somewhere wrong then, well, it'll be tough-er.
I'd do believe that teams can be educated (and have always worked hard on this 
in my teams), but I see your point, so let's simplify the code.

In your case you can make the system more resilient towards programmer error if 
the service actor will do the reply to the client actor. Instead of passing 
down the actor ref to the client, tell the worker to do the work. When it's 
done it should `sender() ! (workId, im done, here's the stuff)`, then the 
service actor can find where it should reply and reply to the client actor. 
Since now the decision is made in one point – in the service actor – if the 
work succeeded of failed, it's simpler to maintain :-)


On Thu, Aug 7, 2014 at 6:09 PM, Lawrence Wagerfield 
lawr...@dmz.wagerfield.com wrote:
It certainly makes sense. I wouldn't expect the send/stop operation to fail any 
more than I would expect the whole supervision framework to fail.

What I'm trying to defend against ultimately comes down to programmer error. 
Its quite likely that I'm being irrational in my perception of how errors might 
be introduced. E.g. a programmer might add some 'exceptional' code after the 
send - that in itself would be a bug, but I'd like for the error to be 
contained and not corrupt the rest of the system with race-conditioned 'failure 
after success' messages.

I believe the approach I posted just before your answer might work, using the 
restart to transmit failure within the transaction itself. It could ensure it 
doesn't send the message if the success message had already been sent.

What are your thoughts? 

(p.s. I know that running with the 'incompetent developer' assumption means 
they could quite-equally cock-up the fault handling code - but providing they 
didn't, it would mean all other exceptions would be handled gracefully.)

On Thursday, August 7, 2014 4:26:33 PM UTC+1, Konrad Malawski wrote:
What I'm playing at is:

Assumptions:
I'm assuming we're talking about all these actors in the same JVM, nothing you 
wrote is hinting a clustered env.

Execution:
If your actor reaches the point in the code where it `client ! result` and does 
nothing (bold italic nothing, as in stopping :-)) afterwards – it just stops 
itself (so no new messages will be processed, even it there are some in the 
mailbox left).

Then, there can be no supervisionStrategy triggering failure as the send is the 
last thing this actor has performed.
Then, there will be no next message processed, because it has stopped, thus no 
such next message can trigger an supervisionStrategy triggering failure.

Which means that, there is no user-land exception that can happen after that 
successful message send.
Exceptions that may trigger the parent's supervision strategy are from there on 
only fatal errors, and from these you are not able to recover a system anyway 
(out of memory etc).

Which means that, there will either be a successful message send and no 
failure, or there will be a failure – so the code will not reach the message 
send.

So, in a local setting, you do not need to do anything more than you currently 
do – just make sure about this last thing my actor does is this send rule.


If we're talking about a distributed setting, it's more difficult, and I 
suggested a solution of this via replying via the master.
client - master - worker // create work
worker -- done-1 -- master -- done-1 -- client

Which creates more message sends, but then the master knows that the job was 
successful.
There are optimisations around this scheme one could apply, but as I understand 
this thread, we're talking local system here.


Hope this helps!



On Thu, Aug 7, 2014 at 4:30 PM, Lawrence Wagerfield 
lawr...@dmz.wagerfield.com wrote:
Are you suggesting the default decider combined with a one-for-one strategy 
with a max retry attempt of 1, combined with the following code?:

override def preRestart(exception)
    client ! exception
    context stop self

On Thursday, August 7, 2014 12:29:05 PM UTC+1, Konrad Malawski 

Re: [akka-user] Synchronising responses sent from parents and children

2014-08-08 Thread Lawrence Wagerfield
It's not the exact code, but the notion is the client receives either a 
success or failure message, not both. In reality I log the exception 
alongside a hash of its message, and then forward that hash to the client. 
It provides us with a way of cross-referencing errors without giving away 
implementation detail.

On Friday, August 8, 2014 1:18:52 PM UTC+1, Konrad Malawski wrote:

 That also works, yes.
 I was unsure if sending the client your failure was OK for you.

 On 8 August 2014 at 14:16:34, Lawrence Wagerfield (
 lawr...@dmz.wagerfield.com javascript:) wrote:
  Hi Konrad, 

 Many thanks for humouring my paranoia! Greatly appreciated.

 I have since implemented another approach that I believe to provide 
 resilience against such an error without the performance hit. Please could 
 you cast your eyes over it? This isn't the exact code, but it captures the 
 workflow:

  // Parent code...
 def supervisorStrategy =
 OneForOneStrategy(loggingEnabled = false, maxNrOfRetries = 1) {
   case _ = Restart
 }

 // Child code...
 override def preRestart(reason: Throwable, message: Option[Any]): Unit =
 if (!responseSent) {
 client ! reason
 context stop self
 }

 On Friday, August 8, 2014 1:09:20 PM UTC+1, Konrad Malawski wrote: 

 Hey Lawrence, 
 If you're willing to sacrifice performance because someone might do 
 something somewhere wrong then, well, it'll be tough-er.
 I'd do believe that teams can be educated (and have always worked hard on 
 this in my teams), but I see your point, so let's simplify the code.

 In your case you can make the system more resilient towards programmer 
 error if the service actor will do the reply to the client actor. Instead 
 of passing down the actor ref to the client, tell the worker to do the 
 work. When it's done it should `sender() ! (workId, im done, here's the 
 stuff)`, then the service actor can find where it should reply and reply 
 to the client actor. Since now the decision is made in one point – in the 
 service actor – if the work succeeded of failed, it's simpler to maintain 
 :-)
  

 On Thu, Aug 7, 2014 at 6:09 PM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com wrote:

  It certainly makes sense. I wouldn't expect the send/stop operation to 
 fail any more than I would expect the whole supervision framework to fail.

 What I'm trying to defend against ultimately comes down to programmer 
 error. Its quite likely that I'm being irrational in my perception of how 
 errors might be introduced. E.g. a programmer might add some 'exceptional' 
 code after the send - that in itself would be a bug, but I'd like for the 
 error to be contained and not corrupt the rest of the system with 
 race-conditioned 'failure after success' messages.

 I believe the approach I posted just before your answer might work, 
 using the restart to transmit failure within the transaction itself. It 
 could ensure it doesn't send the message if the success message had already 
 been sent.

 What are your thoughts? 

 (p.s. I know that running with the 'incompetent developer' assumption 
 means they could quite-equally cock-up the fault handling code - but 
 providing they didn't, it would mean all other exceptions would be handled 
 gracefully.)

 On Thursday, August 7, 2014 4:26:33 PM UTC+1, Konrad Malawski wrote:

  What I'm playing at is: 

 Assumptions:
 I'm assuming we're talking about all these actors in the same JVM, 
 nothing you wrote is hinting a clustered env.

 Execution:
 If your actor reaches the point in the code where it `client ! result` 
 and does *nothing *(bold italic nothing, as in stopping 
 :-)) afterwards – it just *stops* itself (so no new messages will be 
 processed, even it there are some in the mailbox left).

 Then, there can be *no* supervisionStrategy triggering failure as the 
 send is the *last* thing this actor has performed.
 Then, there will be no next message processed, because it has stopped, 
 thus no such next message can trigger an supervisionStrategy triggering 
 failure.
  
 Which means that, there is no user-land exception that can happen after 
 that successful message send.
 Exceptions that may trigger the parent's supervision strategy are from 
 there on only fatal errors, and from these you are not able to recover a 
 system anyway (out of memory etc).
  
 Which means that, there will either be a successful message send and no 
 failure, or there will be a failure – so the code will not reach the 
 message send.

 So, in a local setting, you do not need to do anything more than you 
 currently do – just make sure about this last thing my actor does is this 
 send rule.


 If we're talking about a distributed setting, it's more difficult, and 
 I suggested a solution of this via replying via the master.
 client - master - worker // create work
 worker -- done-1 -- master -- done-1 -- client

 Which creates more message sends, but then the master *knows* that the 
 job was successful.
 There are 

Re: [akka-user] Synchronising responses sent from parents and children

2014-08-08 Thread Lawrence Wagerfield
Haha no worries - it's Friday after all :)

Thank you for all your help.

On Friday, August 8, 2014 1:24:44 PM UTC+1, Konrad Malawski wrote:

 Argh, ignore my last was unsure sentence, mixed up emails :-)
 Yes, the scheme you propose will work correctly, and is definitely harder 
 to mess up than what I suggested.

 Happy hakking!


 On Fri, Aug 8, 2014 at 2:21 PM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com javascript: wrote:

 It's not the exact code, but the notion is the client receives either a 
 success or failure message, not both. In reality I log the exception 
 alongside a hash of its message, and then forward that hash to the client. 
 It provides us with a way of cross-referencing errors without giving away 
 implementation detail.


 On Friday, August 8, 2014 1:18:52 PM UTC+1, Konrad Malawski wrote:

 That also works, yes.
 I was unsure if sending the client your failure was OK for you.

 On 8 August 2014 at 14:16:34, Lawrence Wagerfield (
 lawr...@dmz.wagerfield.com) wrote:
  Hi Konrad, 

 Many thanks for humouring my paranoia! Greatly appreciated.

 I have since implemented another approach that I believe to provide 
 resilience against such an error without the performance hit. Please could 
 you cast your eyes over it? This isn't the exact code, but it captures the 
 workflow:

  // Parent code...
 def supervisorStrategy =
 OneForOneStrategy(loggingEnabled = false, maxNrOfRetries = 1) {
   case _ = Restart
 }

 // Child code...
 override def preRestart(reason: Throwable, message: Option[Any]): Unit =
 if (!responseSent) {
 client ! reason
 context stop self
 }

 On Friday, August 8, 2014 1:09:20 PM UTC+1, Konrad Malawski wrote: 

 Hey Lawrence, 
 If you're willing to sacrifice performance because someone might do 
 something somewhere wrong then, well, it'll be tough-er.
 I'd do believe that teams can be educated (and have always worked hard 
 on this in my teams), but I see your point, so let's simplify the code.

 In your case you can make the system more resilient towards programmer 
 error if the service actor will do the reply to the client actor. Instead 
 of passing down the actor ref to the client, tell the worker to do the 
 work. When it's done it should `sender() ! (workId, im done, here's the 
 stuff)`, then the service actor can find where it should reply and reply 
 to the client actor. Since now the decision is made in one point – in the 
 service actor – if the work succeeded of failed, it's simpler to maintain 
 :-)
  

 On Thu, Aug 7, 2014 at 6:09 PM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com wrote:

  It certainly makes sense. I wouldn't expect the send/stop operation 
 to fail any more than I would expect the whole supervision framework to 
 fail.

 What I'm trying to defend against ultimately comes down to programmer 
 error. Its quite likely that I'm being irrational in my perception of how 
 errors might be introduced. E.g. a programmer might add some 
 'exceptional' 
 code after the send - that in itself would be a bug, but I'd like for the 
 error to be contained and not corrupt the rest of the system with 
 race-conditioned 'failure after success' messages.

 I believe the approach I posted just before your answer might work, 
 using the restart to transmit failure within the transaction itself. It 
 could ensure it doesn't send the message if the success message had 
 already 
 been sent.

 What are your thoughts? 

 (p.s. I know that running with the 'incompetent developer' assumption 
 means they could quite-equally cock-up the fault handling code - but 
 providing they didn't, it would mean all other exceptions would be 
 handled 
 gracefully.)

 On Thursday, August 7, 2014 4:26:33 PM UTC+1, Konrad Malawski wrote:

  What I'm playing at is: 

 Assumptions:
 I'm assuming we're talking about all these actors in the same JVM, 
 nothing you wrote is hinting a clustered env.

 Execution:
 If your actor reaches the point in the code where it `client ! 
 result` and does *nothing *(bold italic nothing, as in stopping 
 :-)) afterwards – it just *stops* itself (so no new messages will be 
 processed, even it there are some in the mailbox left).

 Then, there can be *no* supervisionStrategy triggering failure as 
 the send is the *last* thing this actor has performed.
 Then, there will be no next message processed, because it has 
 stopped, thus no such next message can trigger an supervisionStrategy 
 triggering failure.
  
 Which means that, there is no user-land exception that can happen 
 after that successful message send.
 Exceptions that may trigger the parent's supervision strategy are 
 from there on only fatal errors, and from these you are not able to 
 recover 
 a system anyway (out of memory etc).
  
 Which means that, there will either be a successful message send and 
 no failure, or there will be a failure – so the code will not reach the 
 message send.

 So, in a local setting, you do not need to do 

[akka-user] Synchronising responses sent from parents and children

2014-08-07 Thread Lawrence Wagerfield
I have problem that involves synchronising outbound messages from a parent 
actor and its child actor. This particular problem is with regards to 
forwarding failure messages to clients. 

Here is the example: 

I have a service actor that receives a request from a client actor*.*

The service actor creates a new child transaction actor to deal with said 
request, which then response directly to the client actor after performing 
the work.

If the transaction actor fails, it is stopped by the service actor which 
then sends a failure report to the client actor.

The problem is the client actor must now support receiving failures after 
receiving the response it is actually interested in - otherwise the 
potential 'post-workload' failures from the transaction actor may 
deadletter, or worse, be misinterpreted by the client actor (i.e. a failure 
for a subsequent transaction).

I have considered an approach whereby the client actor must wait for the 
transaction 
actor to terminate before safely continuing, since after that point, it can 
be guaranteed that no more messages will be received.

Is there a common solution to this problem?

-- 
  Read the docs: http://akka.io/docs/
  Check the FAQ: 
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups Akka 
User List group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.


Re: [akka-user] Synchronising responses sent from parents and children

2014-08-07 Thread Konrad Malawski
Hi Lawrence,
In general, exactly one entity in a distributed system should be
responsible for deciding about success / failure,
otherwise there always will be a race of some kind.

In your case though, the problem arrises because the service actor does not
know if the transaction actor has completed the work,
so how about sending the response back through the transaction actor?

Also, in your case, can the transaction actor fail after sending it's
response to the client actor, how would that happen (with a NonFatal
exception)?
I'd expect it to do `client ! stuff; context stop self`, is that not the
case?



On Thu, Aug 7, 2014 at 8:59 AM, Lawrence Wagerfield 
lawre...@dmz.wagerfield.com wrote:

 I have problem that involves synchronising outbound messages from a parent
 actor and its child actor. This particular problem is with regards to
 forwarding failure messages to clients.

 Here is the example:

 I have a service actor that receives a request from a client actor*.*

 The service actor creates a new child transaction actor to deal with said
 request, which then response directly to the client actor after
 performing the work.

 If the transaction actor fails, it is stopped by the service actor which
 then sends a failure report to the client actor.

 The problem is the client actor must now support receiving failures after
 receiving the response it is actually interested in - otherwise the
 potential 'post-workload' failures from the transaction actor may
 deadletter, or worse, be misinterpreted by the client actor (i.e. a
 failure for a subsequent transaction).

 I have considered an approach whereby the client actor must wait for the 
 transaction
 actor to terminate before safely continuing, since after that point, it
 can be guaranteed that no more messages will be received.

 Is there a common solution to this problem?

  --
  Read the docs: http://akka.io/docs/
  Check the FAQ:
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
 ---
 You received this message because you are subscribed to the Google Groups
 Akka User List group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to akka-user+unsubscr...@googlegroups.com.
 To post to this group, send email to akka-user@googlegroups.com.
 Visit this group at http://groups.google.com/group/akka-user.
 For more options, visit https://groups.google.com/d/optout.




-- 
Cheers,
Konrad 'ktoso' Malawski
hAkker @ Typesafe

http://typesafe.com

-- 
  Read the docs: http://akka.io/docs/
  Check the FAQ: 
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups Akka 
User List group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.


Re: [akka-user] Synchronising responses sent from parents and children

2014-08-07 Thread Lawrence Wagerfield
Are you suggesting the default decider combined with a one-for-one strategy 
with a max retry attempt of 1, combined with the following code?:

override def preRestart(exception)
client ! exception
context stop self

On Thursday, August 7, 2014 12:29:05 PM UTC+1, Konrad Malawski wrote:

 Hi Lawrence,
 In general, exactly one entity in a distributed system should be 
 responsible for deciding about success / failure,
 otherwise there always will be a race of some kind.

 In your case though, the problem arrises because the service actor does 
 not know if the transaction actor has completed the work,
 so how about sending the response back through the transaction actor?

 Also, in your case, can the transaction actor fail after sending it's 
 response to the client actor, how would that happen (with a NonFatal 
 exception)?
 I'd expect it to do `client ! stuff; context stop self`, is that not the 
 case?



 On Thu, Aug 7, 2014 at 8:59 AM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com javascript: wrote:

 I have problem that involves synchronising outbound messages from a 
 parent actor and its child actor. This particular problem is with regards 
 to forwarding failure messages to clients. 

 Here is the example: 

 I have a service actor that receives a request from a client actor*.*

 The service actor creates a new child transaction actor to deal with 
 said request, which then response directly to the client actor after 
 performing the work.

 If the transaction actor fails, it is stopped by the service actor which 
 then sends a failure report to the client actor.

 The problem is the client actor must now support receiving failures 
 after receiving the response it is actually interested in - otherwise the 
 potential 'post-workload' failures from the transaction actor may 
 deadletter, or worse, be misinterpreted by the client actor (i.e. a 
 failure for a subsequent transaction).

 I have considered an approach whereby the client actor must wait for the 
 transaction 
 actor to terminate before safely continuing, since after that point, it 
 can be guaranteed that no more messages will be received.

 Is there a common solution to this problem?

  -- 
  Read the docs: http://akka.io/docs/
  Check the FAQ: 
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
 --- 
 You received this message because you are subscribed to the Google Groups 
 Akka User List group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to akka-user+...@googlegroups.com javascript:.
 To post to this group, send email to akka...@googlegroups.com 
 javascript:.
 Visit this group at http://groups.google.com/group/akka-user.
 For more options, visit https://groups.google.com/d/optout.




 -- 
 Cheers,
 Konrad 'ktoso' Malawski
 hAkker @ Typesafe

 http://typesafe.com
  

-- 
  Read the docs: http://akka.io/docs/
  Check the FAQ: 
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups Akka 
User List group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.


Re: [akka-user] Synchronising responses sent from parents and children

2014-08-07 Thread Konrad Malawski
What I'm playing at is:

Assumptions:
I'm assuming we're talking about all these actors in the same JVM, nothing
you wrote is hinting a clustered env.

Execution:
If your actor reaches the point in the code where it `client ! result` and
does *nothing *(bold italic nothing, as in stopping :-)) afterwards – it
just *stops* itself (so no new messages will be processed, even it there
are some in the mailbox left).

Then, there can be *no* supervisionStrategy triggering failure as the send
is the *last* thing this actor has performed.
Then, there will be no next message processed, because it has stopped, thus
no such next message can trigger an supervisionStrategy triggering failure.

Which means that, there is no user-land exception that can happen after
that successful message send.
Exceptions that may trigger the parent's supervision strategy are from
there on only fatal errors, and from these you are not able to recover a
system anyway (out of memory etc).

Which means that, there will either be a successful message send and no
failure, or there will be a failure – so the code will not reach the
message send.

So, in a local setting, you do not need to do anything more than you
currently do – just make sure about this last thing my actor does is this
send rule.


If we're talking about a distributed setting, it's more difficult, and I
suggested a solution of this via replying via the master.
client - master - worker // create work
worker -- done-1 -- master -- done-1 -- client

Which creates more message sends, but then the master *knows *that the job
was successful.
There are optimisations around this scheme one could apply, but as I
understand this thread, we're talking *local *system here.


Hope this helps!



On Thu, Aug 7, 2014 at 4:30 PM, Lawrence Wagerfield 
lawre...@dmz.wagerfield.com wrote:

 Are you suggesting the default decider combined with a one-for-one
 strategy with a max retry attempt of 1, combined with the following code?:

 override def preRestart(exception)
 client ! exception
 context stop self

 On Thursday, August 7, 2014 12:29:05 PM UTC+1, Konrad Malawski wrote:

 Hi Lawrence,
 In general, exactly one entity in a distributed system should be
 responsible for deciding about success / failure,
 otherwise there always will be a race of some kind.

 In your case though, the problem arrises because the service actor does
 not know if the transaction actor has completed the work,
 so how about sending the response back through the transaction actor?

 Also, in your case, can the transaction actor fail after sending it's
 response to the client actor, how would that happen (with a NonFatal
 exception)?
 I'd expect it to do `client ! stuff; context stop self`, is that not the
 case?



 On Thu, Aug 7, 2014 at 8:59 AM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com wrote:

 I have problem that involves synchronising outbound messages from a
 parent actor and its child actor. This particular problem is with regards
 to forwarding failure messages to clients.

 Here is the example:

 I have a service actor that receives a request from a client actor*.*

 The service actor creates a new child transaction actor to deal with
 said request, which then response directly to the client actor after
 performing the work.

 If the transaction actor fails, it is stopped by the service actor which
 then sends a failure report to the client actor.

 The problem is the client actor must now support receiving failures
 after receiving the response it is actually interested in - otherwise the
 potential 'post-workload' failures from the transaction actor may
 deadletter, or worse, be misinterpreted by the client actor (i.e. a
 failure for a subsequent transaction).

 I have considered an approach whereby the client actor must wait for
 the transaction actor to terminate before safely continuing, since
 after that point, it can be guaranteed that no more messages will
 be received.

 Is there a common solution to this problem?

  --
  Read the docs: http://akka.io/docs/
  Check the FAQ: http://doc.akka.io/docs/akka/
 current/additional/faq.html
  Search the archives: https://groups.google.com/
 group/akka-user
 ---
 You received this message because you are subscribed to the Google
 Groups Akka User List group.
 To unsubscribe from this group and stop receiving emails from it, send
 an email to akka-user+...@googlegroups.com.
 To post to this group, send email to akka...@googlegroups.com.

 Visit this group at http://groups.google.com/group/akka-user.
 For more options, visit https://groups.google.com/d/optout.




 --
 Cheers,
 Konrad 'ktoso' Malawski
 hAkker @ Typesafe

 http://typesafe.com

  --
  Read the docs: http://akka.io/docs/
  Check the FAQ:
 http://doc.akka.io/docs/akka/current/additional/faq.html
  Search the archives: https://groups.google.com/group/akka-user
 ---
 You received this message because you are subscribed to the Google Groups
 Akka User List group.
 To unsubscribe from 

Re: [akka-user] Synchronising responses sent from parents and children

2014-08-07 Thread Lawrence Wagerfield
It certainly makes sense. I wouldn't expect the send/stop operation to fail 
any more than I would expect the whole supervision framework to fail.

What I'm trying to defend against ultimately comes down to programmer 
error. Its quite likely that I'm being irrational in my perception of how 
errors might be introduced. E.g. a programmer might add some 'exceptional' 
code after the send - that in itself would be a bug, but I'd like for the 
error to be contained and not corrupt the rest of the system with 
race-conditioned 'failure after success' messages.

I believe the approach I posted just before your answer might work, using 
the restart to transmit failure within the transaction itself. It could 
ensure it doesn't send the message if the success message had already been 
sent.

What are your thoughts? 

(p.s. I know that running with the 'incompetent developer' assumption means 
they could quite-equally cock-up the fault handling code - but providing 
they didn't, it would mean all other exceptions would be handled 
gracefully.)

On Thursday, August 7, 2014 4:26:33 PM UTC+1, Konrad Malawski wrote:

 What I'm playing at is:

 Assumptions:
 I'm assuming we're talking about all these actors in the same JVM, nothing 
 you wrote is hinting a clustered env.

 Execution:
 If your actor reaches the point in the code where it `client ! result` and 
 does *nothing *(bold italic nothing, as in stopping :-)) afterwards – 
 it just *stops* itself (so no new messages will be processed, even it 
 there are some in the mailbox left).

 Then, there can be *no* supervisionStrategy triggering failure as the 
 send is the *last* thing this actor has performed.
 Then, there will be no next message processed, because it has stopped, 
 thus no such next message can trigger an supervisionStrategy triggering 
 failure.

 Which means that, there is no user-land exception that can happen after 
 that successful message send.
 Exceptions that may trigger the parent's supervision strategy are from 
 there on only fatal errors, and from these you are not able to recover a 
 system anyway (out of memory etc).

 Which means that, there will either be a successful message send and no 
 failure, or there will be a failure – so the code will not reach the 
 message send.

 So, in a local setting, you do not need to do anything more than you 
 currently do – just make sure about this last thing my actor does is this 
 send rule.


 If we're talking about a distributed setting, it's more difficult, and I 
 suggested a solution of this via replying via the master.
 client - master - worker // create work
 worker -- done-1 -- master -- done-1 -- client

 Which creates more message sends, but then the master *knows *that the 
 job was successful.
 There are optimisations around this scheme one could apply, but as I 
 understand this thread, we're talking *local *system here.


 Hope this helps!

  

 On Thu, Aug 7, 2014 at 4:30 PM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com javascript: wrote:

 Are you suggesting the default decider combined with a one-for-one 
 strategy with a max retry attempt of 1, combined with the following code?:

 override def preRestart(exception)
 client ! exception
 context stop self

 On Thursday, August 7, 2014 12:29:05 PM UTC+1, Konrad Malawski wrote:

 Hi Lawrence,
 In general, exactly one entity in a distributed system should be 
 responsible for deciding about success / failure,
 otherwise there always will be a race of some kind.

 In your case though, the problem arrises because the service actor does 
 not know if the transaction actor has completed the work,
 so how about sending the response back through the transaction actor?

 Also, in your case, can the transaction actor fail after sending it's 
 response to the client actor, how would that happen (with a NonFatal 
 exception)?
 I'd expect it to do `client ! stuff; context stop self`, is that not the 
 case?



 On Thu, Aug 7, 2014 at 8:59 AM, Lawrence Wagerfield 
 lawr...@dmz.wagerfield.com wrote:

 I have problem that involves synchronising outbound messages from a 
 parent actor and its child actor. This particular problem is with regards 
 to forwarding failure messages to clients. 

 Here is the example: 

 I have a service actor that receives a request from a client actor*.*

 The service actor creates a new child transaction actor to deal with 
 said request, which then response directly to the client actor after 
 performing the work.

 If the transaction actor fails, it is stopped by the service actor which 
 then sends a failure report to the client actor.

 The problem is the client actor must now support receiving failures 
 after receiving the response it is actually interested in - otherwise the 
 potential 'post-workload' failures from the transaction actor may 
 deadletter, or worse, be misinterpreted by the client actor (i.e. a 
 failure for a subsequent transaction).

 I have considered an approach whereby the client