Hi Sean,

removing the self-type would not help: its function is only to ensure that 
every ActorRef also has an appropriate implementation, basically proving that 
the down-cast that is used in many places in the implementation will work out 
fine. In the end every ActorRef needs to support the sendSystem method (not 
equally sure about isLocal, due to missing remoting implementation).

Patrik & team: what is your opinion on this? Should sendSystem become visible 
in order to make ActorRef implementable by user code? In any case we should 
probably prominently point out that suitable stubs for ActorRef and 
ActorContext are provided in the form of Inbox and EffectfulActorContext, and 
that rolling your own is typically not necessary.

On stubbing out ActorSystem or making it easier to override, I have mixed 
feelings: it is a quite complicated machine that is not easy to modify 
correctly—and it is also not easy to provide a stub that actually works, due to 
some semantic requirements. I completely understand that just counting calls to 
terminate() may seem to contradict my statement, but consider the other side of 
the coin: if ActorSystem were as you want it, then people would modify it also 
in cases where that is not appropriate.

To answer your concrete question, a much easier way of ensuring correct 
shutdown would be to supply a function of type () => Unit to the actor that 
shall call it. Production code would supply () => system.terminate(), but the 
test could provide whatever you want.

Regards,

Roland

> 25 aug. 2017 kl. 04:01 skrev Sean Shubin <[email protected]>:
> 
> I had a chance to look over the typed actors a bit more.  Here is my 
> feedback.  Whether you agree or disagree, I hope you find it useful.  I am 
> still really excited about typed actors, the main reason I have been 
> reluctant to switch to akka is that I was not willing to give up static 
> typing.  
> 
> Behavior by itself is easy to test as long as you are not doing anything with 
> ActorContext.  I particularly like the separation of the management method to 
> deal with lifecycle signals, from the message method to deal with messages.
> 
> ActorContext can't be stubbed out because it leaks out the private classes 
> InternalActorRef and ActorSystemImpl through its protected methods 
> lookupRoot, guardian, and systemImpl.
> 
> ActorRef can't be stubbed out because of the self type on 
> internal.ActorRefImpl.  I have already demonstrated issue with this in detail 
> with my FooApp and BarApp examples in this thread.  I did look up the 
> ScalaDoc for ActorRefImpl, and while I think its fine to hide the sendSystem 
> and isLocal methods, I do think that if these methods were pushed down into a 
> class that inherits from ActorRef, rather than using a self type, that would 
> make it easier to stub out ActorRef.
> 
> ActorSystem has the same problem as ActorRef for the same reason, but it 
> manifests much worse because the ActorSystem trait has so many more methods.  
> To see why, consider writing a unit test to make sure an actor system is 
> properly shut down once the program is finished.  I want to test the code 
> here:
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystems.scala
> It should be as easy as this:
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystemsTest.scala
> And from looking at this test it seems like it is, but look what I had to do 
> to get to this point:
> On my dependency injection class I had to add another level of indirection
>   val eventActorSystem: ActorSystem[Event] = ActorSystem("state", stateful)
>   val eventActorSystemContract: ActorSystemContract[Event] = 
>     new ActorSystemDelegate[Event](eventActorSystem)
> I had to hide ActorSystem behind an interface
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/ActorSystemContract.scala
> And then delegate to the real ActorSystem
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/main/scala/com/seanshubin/concurrency/samples/actor/ActorSystemDelegate.scala
> That way, for testing I could start with a class where nothing is implemented:
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/ActorSystemNotImplemented.scala
> Then use that not implemented class as a base for my stub
>   class ActorSystemStub extends ActorSystemNotImplemented[Event] {
>     var terminateInvocationCount = 0
> 
>     override def terminate(): Future[Terminated] = {
>       terminateInvocationCount += 1
>       null
>     }
>   }
> Which I finally use in my test
> https://github.com/SeanShubin/concurrency-samples/blob/master/actor/src/test/scala/com/seanshubin/concurrency/samples/actor/CleanupActorSystemsTest.scala
> 
> My impression is that most of these problems stem from exposing classes to 
> the user that are too concrete.  If we could push some of these 
> implementation details like private clases and self types further down the 
> inheritance chain, and remove the need for client code to have a compile time 
> dependency on the implementation details, it would be much easier to stub out 
> interactions and have fully unit-tested code.
> 
> 
> -- 
> >>>>>>>>>> Read the docs: http://akka.io/docs/ <http://akka.io/docs/>
> >>>>>>>>>> Check the FAQ: 
> >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html 
> >>>>>>>>>> <http://doc.akka.io/docs/akka/current/additional/faq.html>
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user 
> >>>>>>>>>> <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] 
> <mailto:[email protected]>.
> To post to this group, send email to [email protected] 
> <mailto:[email protected]>.
> Visit this group at https://groups.google.com/group/akka-user 
> <https://groups.google.com/group/akka-user>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
>>>>>>>>>>      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 https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to