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 <
> [email protected] <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 (
>>> [email protected]) 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 <
>>>> [email protected]> 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 <
>>>>>> [email protected]> 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 <
>>>>>>>> [email protected]> 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 [email protected].
>>>>>>>>> To post to this group, send email to [email protected]. 
>>>>>>>>>
>>>>>>>>> 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 [email protected].
>>>>>>> To post to this group, send email to [email protected].
>>>>>>> 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 [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> 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 [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at http://groups.google.com/group/akka-user.
>>> For more options, visit https://groups.google.com/d/optout.
>>>  -- 
>>> Konrad 'ktoso' Malawski
>>> hAkker @ typesafe
>>> http://akka.io
>>>
>>  -- 
>> >>>>>>>>>> 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 [email protected] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to