These are chat archives for akkadotnet/akka.net

29th
Jun 2017
Anders Storhaug
@andersstorhaug
Jun 29 2017 01:36
Like switchable behaviors quite a bit, but running into cases where I find myself wanting state machines that run in the context of a single actor. For instance, I might have to frequently observe the state of a number of state machines, and using stateMachineActor.Ask<T>(message) feels wrong (and probably is wrong, from a perf perspective for my usecase). Kind of like the lambda implementation with closures around state-specific variables, though. Anyone know if there's a state machine lib that's implemented in a similar fashion to switchable behaviors?
Andrey Leskov
@andreyleskov
Jun 29 2017 09:02
+1 for Automatonymous, successfully using it for Sagas \ Process Manager
Stephen Newman
@goodisontoffee
Jun 29 2017 12:09
Does anyone know if "strange things" should happen with TestKit testing an actor inheriting from ReceivePersistentActor? I don't know how to explain it but it "feels" as though something happens to the single threaded nature of TestKit.
Stephen Newman
@goodisontoffee
Jun 29 2017 12:17
Bizzarely turning message serialization on seems to cure it, the test is checking that the expected message is returned and part of that is obtained via UnderlyingActor.SomeProperty - which at the time of being queried is return a default value, but the message handler DOES set it. Message is sent prior to UnderlyingActor being inspected, hence my feeling that the single threaded nature is being broken somewhere by Akka.Persistence.
Andrey Leskov
@andreyleskov
Jun 29 2017 12:47
@goodisontoffee can you please provide an example? I'm testing ReceivePersistentActor with TestKit and never had such issues
Stephen Newman
@goodisontoffee
Jun 29 2017 12:47

Scenario is as such:
1) Tell actor under test a message
2) Construct the expected result (using a property accessed via UnderlyingActor)
3) Fish for a message of a particular type
4) Compare received message with expected

This fails, swapping the positions of 2 and 3 fixes the issue but it seems strange to me.

@andreyleskov I can't share this specific code, but I might be able to make something that illustrates the point that I can share, but I've tried to outline what's going on in my previous message.
Stephen Newman
@goodisontoffee
Jun 29 2017 12:54
I can also "solve" the problem by System.Threading.Thread.Sleep(2000); which confuses me no end as I believed that actorsystem used by TestKit was single threaded
Andrey Leskov
@andreyleskov
Jun 29 2017 13:00
how do you pass message to actor?
do you await message processing ?
zbynek001
@zbynek001
Jun 29 2017 13:02
why OnReceive method on UntypedActor is not returning bool? How can I say that the message was not processed?Is there even any advantage using UntypedActor instead of ActorBase direclty?
Andrey Leskov
@andreyleskov
Jun 29 2017 13:02
@goodisontoffee following test works ok:
   public class PeristenceAsyncTest : TestKit
    {
        class TestingActor : ReceivePersistentActor
        {
            public TestingActor(){Command<int>(i =>{State = i;Sender.Tell(i);});}
            public int State { get; set; }
            public override string PersistenceId { get; } = "1";
        }

        [Fact]
        public async Task Test()
        {
            var actor = ActorOfAsTestActorRef(() => new TestingActor());
            await actor.Ask<int>(10);
            Assert.Equal(10,actor.UnderlyingActor.State);
        }
    }
please adjust it to reproduce your situation
Stephen Newman
@goodisontoffee
Jun 29 2017 13:03
```
public class PeristenceAsyncTest : TestKit
{
class TestingActor : ReceivePersistentActor
{
public TestingActor(){Command<int>(i =>{State = i;Sender.Tell(i);});}
public int State { get; set; }
public override string PersistenceId { get; } = "1";
}
    [Fact]
    public void Test()
    {
        var actor = ActorOfAsTestActorRef(() => new TestingActor());
        actor.Tell<int>(10);
        Assert.Equal(10,actor.UnderlyingActor.State);
    }
}
Alex Valuyskiy
@alexvaluyskiy
Jun 29 2017 13:03
@zbynek001 You can use ActorBase It's method Receive return bool
Stephen Newman
@goodisontoffee
Jun 29 2017 13:03
That should do the job
Alex Valuyskiy
@alexvaluyskiy
Jun 29 2017 13:04
For UntypedActor you could use Unhandled(message) method
Andrey Leskov
@andreyleskov
Jun 29 2017 13:05
@goodisontoffee Tell() will not work for sure, because there is no guarantee message will be processed after exiting from Tell()
Alex Valuyskiy
@alexvaluyskiy
Jun 29 2017 13:05
There is no any real advantages between UntypedActor and ActorBase. UntypedActor is a bit high level. Very useful if you don't want to return true/false everywhere
Andrey Leskov
@andreyleskov
Jun 29 2017 13:05
Does not work and it is OK!
Stephen Newman
@goodisontoffee
Jun 29 2017 13:06
@andreyleskov They have been working fine until I got Persistence involve
Are you saying that's fine for you?
Andrey Leskov
@andreyleskov
Jun 29 2017 13:08
@goodisontoffee
 public class PeristenceAsyncTest : TestKit
   {
       class TestingActor : ReceiveActor
       {
           public TestingActor(){Receive<int>(i => {State = i;
                                                    Thread.Sleep(100);
                                              });}
           public int State { get; set; }
       }

       [Fact]
       public void Test()
       {
           var actor = ActorOfAsTestActorRef(() => new TestingActor());
           actor.Tell(10);
           Assert.Equal(10,actor.UnderlyingActor.State);
       }
   }
ReceiveActor works as you described. Seems I never use this behavior )
also works with ReceiveAsync
Stephen Newman
@goodisontoffee
Jun 29 2017 13:14
@andreyleskov if you make TestingActor a ReceivePersistentActor and see if it still works?
Andrey Leskov
@andreyleskov
Jun 29 2017 13:15
nope, try run code from my first example
Stephen Newman
@goodisontoffee
Jun 29 2017 13:15
will do
zbynek001
@zbynek001
Jun 29 2017 13:30
@alexvaluyskiy thx
Ilya Komendantov
@IlyaKomendantov_twitter
Jun 29 2017 13:41
Hi,
Is there a possibility to use 'Persistence Queue' without having the DB running? For testing purposes :)
I have persistence actors "in-memory" and I want to already segregate read and write sides..
Alex Valuyskiy
@alexvaluyskiy
Jun 29 2017 13:45
@IlyaKomendantov_twitter The InMemory journal does not support Persistence Query
Ilya Komendantov
@IlyaKomendantov_twitter
Jun 29 2017 13:45
:(
Andy Kutruff
@akutruff
Jun 29 2017 16:14
Howdy,
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:15
hi Andy
take it you saw my comment :p
Andy Kutruff
@akutruff
Jun 29 2017 16:15
Hey Aaron. Yep!
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:15
some of our earliest adopters, years ago, were Unity users
Andy Kutruff
@akutruff
Jun 29 2017 16:15
Sorry, I know it was issues and I try to not let those devolve into forum posts, but alas
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:15
unfortunately due to the state of their runtime we couldn't do a heck of a lot to get Akka.NET running on the client
Andy Kutruff
@akutruff
Jun 29 2017 16:16
Yeah, there's a tale of two worlds with Unity - those who need AOT (iOS) and those that don't
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:16
but that story has changed now
yep, well maybe we can find a happy middle
Andy Kutruff
@akutruff
Jun 29 2017 16:16
Yeah, totally, which is why I'm challenging our internal engine with Akka.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:17
so yeah, TL;DR; none of us know much about the particulars of the unity compiler but we're eager to learn and help
Andy Kutruff
@akutruff
Jun 29 2017 16:17
For games, we try to keep the backend and front end code identical
(and keep allocations low)
So with AOT it sucks - you kind of have an arm tied behind your back with reflection.emit and some forms of generic interfaces
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:18
Andy Kutruff
@akutruff
Jun 29 2017 16:18
If you want a dynamic-ish portion of your code, you end up having to do a compile-time codegen step
Yeah, basically, but there's a bit more to the onion and edge cases that Unity sucks at documenting. Also, they really don't emphasize how IL2CPP can end up generating a huge (100+MB) binary from using generics with value types.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:20
ouch
Andy Kutruff
@akutruff
Jun 29 2017 16:20
Yeah, for Unity iOS people you need your binary to be under that limit because users will need to be on a wifi connection to install your game
Unless you're blizzard who has no problem getting users, it's a nonstarter for my clients
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:21
so the IL2CPP stuff is basically like compiling a statically linked native app then right?
yeah, I sympathize - I originally started on Akka.NET when I was writing mobile analytics software
Andy Kutruff
@akutruff
Jun 29 2017 16:21
Yeah. It takes IL and spits out C++. It's pretty slick in a lot of ways, and they have to do it because Apple's unfortunate security lockdown
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:21
had to keep SDK install size and bandwidth footprint to a minimum
Andy Kutruff
@akutruff
Jun 29 2017 16:22
It's rough going, but things that are hard to solve are a good way to be special in the industry. : )
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:22
agreed
so one thing that jumps to my mind immediately here
in terms of being able to help make Akka.NET workable on Unity3D
is resurrecting my favorite pet project
Gregorius Soedharmo
@Arkatufus
Jun 29 2017 16:23
would it be better to wait until unity release their new .net 4.5 support?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:23
back when we shipped Akka.NET 1.1 last year, it turned out that we were sending critical system messages through IActorRef.Tell instead of IInternalActorRef.SendSystemMessage
and that made things like deathwatch behave weirdly
so I wrote an analyzer to see where we were doing that and fix it
since manually combing through the code wasn't an option
Andy Kutruff
@akutruff
Jun 29 2017 16:24
Unity has .NET 4.6 support in their latest release. It's marked experimental, but is proving to be rather (surprisingly) stable
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:24
one thing we could do is take these AOT compilation rules
Gregorius Soedharmo
@Arkatufus
Jun 29 2017 16:25
oh, its out already? that was fast
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:25
and express them as Roslyn analyzer rules
Andy Kutruff
@akutruff
Jun 29 2017 16:25
It's been in beta for years.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:25
looking for things like generic virtual methods should be a no-brainer
Andy Kutruff
@akutruff
Jun 29 2017 16:25
Hmm. This is running in the IDE or runtime?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:26
Reflection.Emit will be trickier, since you'll want to know where this being called internally by other .NET methods
in the IDE initially
if we got creative and figured out how to add it to the build pipeline
Gregorius Soedharmo
@Arkatufus
Jun 29 2017 16:26
well, changing code base can be a bleep, its surprising that they manage to port to 4.6 that fast, considering that they put up doing it for years and years due to backward incompatibility issues
Andy Kutruff
@akutruff
Jun 29 2017 16:26
Reflection.Emit is somewhat easy to avoid in the main BCL.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:26
we could have it flag errors on the compilation stage too on the build server
but that way the knowledge on how to keep things compliant with Unity's rules becomes ingrained in the tooling
Andy Kutruff
@akutruff
Jun 29 2017 16:27
Yeah, would be rad. I mean it comes down to how much restriction you're willing to live with in Akka, or what pieces you're willing to carve out with these restrictions to support AOT
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:27
rather than having to be passed on via oral history to all of the maintainers
Andy Kutruff
@akutruff
Jun 29 2017 16:27
Yeah, that's super sound engineering
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:28
well, first thing we'd probably do is see if we can live without it in a few areas
Andy Kutruff
@akutruff
Jun 29 2017 16:28
At least now you can test IL2CPP on windows and not have to load it on the actual phone.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:28
like starting up the system actors in ActorSystem.Create
but if there's something nasty like having to rewrite all of the Akka.Remote actors to no longer use ReceiveActor
Andy Kutruff
@akutruff
Jun 29 2017 16:29
yeah, that's what put the breaks on for me. I saw Props, and had flashbacks to when I did Lambda caching. Emit wasn't the problem then, it was actually garbage collection pressure and the equality operators. Snake eating it's tail
Why does Receive actor need Emit?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:30
I don't think it does
Andy Kutruff
@akutruff
Jun 29 2017 16:30
It's a type dispatch table.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:30
anyway, where I was going with that
worst case scenario
return to the land of pre-compilation directives
and shipping a separate NuGet target for Unity
which would take a lot longer to do - we're definitely not prepared to do that now with all of the work that's still going into supporting separate .NET Core targets for v1.3
Andy Kutruff
@akutruff
Jun 29 2017 16:32
What's your thinking for making it a separate package? I wouldn't actually link to UnityEngine.dll if that's what's in your head
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:32
I was thinking if we had problematic bits of code that needed to have a custom unity-specific implementation in order to comply with the AOT rules
and for some reason, like performance or API compatibility, we didn't want to do that with the main project
anyway, this is just me thinking outloud
Andy Kutruff
@akutruff
Jun 29 2017 16:34
Oh, yeah, I was just hoping you wouldn't have to go all the way to the nuget level rather than putting a compiler constant in there, but then again, nuget would be safer to enforce client/server are actually running the same code
Thinking is how things get done. : )
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:35
so here's what I would propose: let's transform your issue into "support AOT compilation for Unity3D"
Andy Kutruff
@akutruff
Jun 29 2017 16:35
So for me, I'm about to start a big 14 month project, and I'm really wanting to give Akka it's day in court, and I really would love to be able to carve out the most minimal client server actor scenario and have it run on an iPhone
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:35
and build a definitive list of blocking issues that stop you from using each module
Andy Kutruff
@akutruff
Jun 29 2017 16:35
So I'm assuming that would be a fork for now.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:35
sounds like Akka core + Akka.Remote are the two you need
yeah, you should fork it and send in some pull requests :p
Andy Kutruff
@akutruff
Jun 29 2017 16:36
Yep. I bet if I can isolate Emit() I can get it there, but I'm worried about the serialization... Hyperion, right?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:36
the serialization is swappable
and Hyperion is going to get a major facelift
Andy Kutruff
@akutruff
Jun 29 2017 16:36
What about persistance?
That's the step 2 - event sourcing
Those two tick boxes, and I can greenlight
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:37
add that to the list too
IMHO for you, I'd avoid the polymorphic serializers
they're going to do all sorts of crazy reflection and type emission stuff
Andy Kutruff
@akutruff
Jun 29 2017 16:37
Yeah, our messages don't have reference types in them
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:37
go with something static like protobufs
Andy Kutruff
@akutruff
Jun 29 2017 16:37
only Id's
Yep, we use protobufs
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:38
so even though Akka.NET lists JSON.NET / Hyperion as a NuGet package dependency
you don't need either of them to compile
Akka.Remote does strictly depend on Protobuf for its control messages
Andy Kutruff
@akutruff
Jun 29 2017 16:38
For either of them, it is actually okay for emit code to end up in the compilation, it's a runtime issue
As long as you don't actually execute a codepath with no-no, you're cool
Yeah, I have it compiling a running totally fine under AOT
As long as protobuf isn't emitting, all is good. It's just such a easy optimization, it ends up in codebases early
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:41
with something like Hyperion or JSON.NET
I'd have to look through the internals, but yeah
I'm less confident that would work fine at runtime under those constraints
Andy Kutruff
@akutruff
Jun 29 2017 16:41
I had to role our own protobufs for AOT back in the day - emit was everywhere else, but I'll take a peek at mainline protobuf again
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:42
1.3 is swapping to Protobuf3
which is .NET Standard
Andy Kutruff
@akutruff
Jun 29 2017 16:42
Good thing about the Unity/Game world, things tend to be simple in their stuff.
1.3 is not stable though right?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:42
not yet
especially with Akka.Persistence
that's leaving beta in this release
Andy Kutruff
@akutruff
Jun 29 2017 16:43
Oh, it's beta in 1.2?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:43
so we're refining the API down it its stable form
yeah
Andy Kutruff
@akutruff
Jun 29 2017 16:43
hmmm... how beta? :)
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:43
all of the big picture stuff still works, like persistent actors
akkadotnet/akka.net#2743
that outlines the changes in a lot of detail
Akka.Persistence has been used in production for years
but it's been a moving target in some areas, especially serialization
Andy Kutruff
@akutruff
Jun 29 2017 16:45
Hmm. so can I get the 1km view of this prop matchbuilder stuff?
Cool, yeah the fact Akka is mature is why I'm really hoping it works out for us
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:46
the Props class?
or the ReceiveActor matching stuff?
Andy Kutruff
@akutruff
Jun 29 2017 16:46
It appears there's some signature system or something that is trying to use reflection to extract something for this lambda cache
I don't see where to begin somewhat
The CreateSystem call and the systemguardian
Like, why is there a lambda cache at all? Why use expression trees?
Is it something DI-lie?
*like
and all of the stuff in that folder
Andy Kutruff
@akutruff
Jun 29 2017 16:48
Yeah, but what is Akka using it for? This call stack
NotSupportedException: C:\Temp\AkkaTest\Il2CppOutputProject\IL2CPP\libil2cpp\icalls\mscorlib\System.Reflection.Emit\AssemblyBuilder.cpp(20) : Unsupported internal call for IL2CPP:AssemblyBuilder::basic_init - System.Reflection.Emit is not supported.
at System.AppDomain.DefineDynamicAssembly (System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, System.String dir, System.Security.Policy.Evidence evidence, System.Security.PermissionSet requiredPermissions, System.Security.PermissionSet optionalPermissions, System.Security.PermissionSet refusedPermissions, System.Boolean isSynchronized) [0x00000] in <00000000000000000000000000000000>:0
at System.AppDomain.DefineDynamicAssembly (System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.Emit.DynamicMethod+AnonHostModuleHolder..cctor () [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes, System.Type owner, System.Reflection.Module m, System.Boolean skipVisibility, System.Boolean anonHosted) [0x00000] in <00000000000000000000000000000000>:0
at System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Type returnType, System.Type[] parameterTypes, System.Boolean restrictedSkipVisibility) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Compiler.LambdaCompiler..ctor (System.Linq.Expressions.Compiler.AnalyzedTree tree, System.Linq.Expressions.LambdaExpression lambda) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Compiler.LambdaCompiler.Compile (System.Linq.Expressions.LambdaExpression lambda, System.Runtime.CompilerServices.DebugInfoGenerator debugInfoGenerator) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Expression1[TDelegate].Compile () [0x00000] in <00000000000000000000000000000000>:0 at Akka.Util.Reflection.ExpressionExtensions.GetArguments (System.Linq.Expressions.NewExpression newExpression) [0x00000] in <00000000000000000000000000000000>:0 at Akka.Actor.Props.Create[TActor] (System.Linq.Expressions.Expression1[TDelegate] factory, Akka.Actor.SupervisorStrategy supervisorStrategy) [0x00000] in <00000000000000000000000000000000>:0
at Akka.Actor.LocalActorRefProvider.CreateSystemGuardian (Akka.Actor.LocalActorRef rootGuardian, System.String name, Akka.Actor.LocalActorRef userGuardian) [0x00000] in <00000000000000000000000000000000>:0
at Akka.Actor.LocalActorRefProvider.Init (Akka.Actor.Internal.ActorSystemImpl system) [0x00000] in <00000000000000000000000000000000>:0
at Akka.Actor.Internal.ActorSystemImpl.Start () [0x00000] in <00000000000000000000000000000000>:0
at Akka.Actor.ActorSystem.Create (System.String name) [0x00000] in <00000000000000000000000000000000>:0
at Chat.ChatClientProgram.RunTheChatClientWithNoScoping () [0x00000] in <00000000000000000000000000000000>:0
at UnityScripts.ApplicationInitializer.Awake () [0x00000] in <00000000000000000000000000000000>:0
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:49
let me pull up the relevant source rq
Andy Kutruff
@akutruff
Jun 29 2017 16:49
The GetArguments() call you mentioned
that's one possibility
let me grab the other
Andy Kutruff
@akutruff
Jun 29 2017 16:51
I'm maybe too new to Akka, haven't even gotten to the purpose of Props yet.
I assumed it's a property bag of sorts
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:51
Props describes how to start an actor
it provides the constructor arguments
and is used to instantiate the actor
Andy Kutruff
@akutruff
Jun 29 2017 16:52
To avoid overload-hell?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:52
and provides some configuration details about it, such as whether to use a specific dispatcher, mailbox, or to be a router
mostly to hide the implementation details of how an actor starts from everything else
Props most important function is actor restarts
when an actor restarts, it has to reboot into a well-known "safe" state
Andy Kutruff
@akutruff
Jun 29 2017 16:53
So it's like a micro DSL
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:53
that state is defined by "the initial state created by this actor's Props"
in a persistent actor, that state is that plus whatever events can be recovered
from the durable store
Andy Kutruff
@akutruff
Jun 29 2017 16:54
hmm... how's that version to version resiliant?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:54
because Props is defined at the binary level within one assembly
it'd fail at compile-time
if there was an issue
however, you can run into fun problems with remote actor deployment with Props
when you remotely instantiate an actor over the network
Andy Kutruff
@akutruff
Jun 29 2017 16:55
I mean if you're storing the props to the database for akka version 1.2, it's the same problem as the messages themselves
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:55
ah no, we don't store Props in the database
Andy Kutruff
@akutruff
Jun 29 2017 16:55
okay, sorry, misunderstood
"durable store"
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:55
the persistent actor starts with whatever Props gives it
and then it begins recovering from the durable store
before it accepts any messages
that's implemented using behavior-switching under the hood
Andy Kutruff
@akutruff
Jun 29 2017 16:55
Okay, glad to hear that
that's the pushdown FSM-ish stuff, right?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:56
yeah
most behavior-switching doesn't use the behavior stack these days
Andy Kutruff
@akutruff
Jun 29 2017 16:56
So backing up, what problem does reflectoin solve for implementing props?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:56
ah, so that code I linked
in that case literally all we're doing is extracting the constructor arguments from the Expression
we're not actually invoking the expression at all
what that gives us is compile-time safety
lets the end-user know that they've satisfied that actor's constructor argument requirements at compilation
IMHO, this is probably not what is generating the error
Andy Kutruff
@akutruff
Jun 29 2017 16:58
It's calling Compile though...
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:58
... I think it's this
that line should only be called when it's DI that's instantiating the actor
the DynamicProps bit
Andy Kutruff
@akutruff
Jun 29 2017 16:59
sorry, which line?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 16:59
any time you're using a regular-old new expression
Andy Kutruff
@akutruff
Jun 29 2017 17:00
still missing the motivation here of the expression tree. It allows me to use a lambda for instead of having to _
oops. did not meand for that to bold
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:01
getting to that, I think the error being thrown is coming from this
Andy Kutruff
@akutruff
Jun 29 2017 17:01
still missing the motivation here of the expression tree. It allows me to use a lambda for X instead of having to Y
That's what I meant to type
oh okay
_systemGuardian = CreateSystemGuardian(_rootGuardian, "system", _userGuardian);
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:02
that's the line that throws
buuuuuuuut
Andy Kutruff
@akutruff
Jun 29 2017 17:03
Oh, so this is monad-ish
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:03
aha, no you're right
I was assuming that SystemGuardianActor was a receive actor
but it isn't
Andy Kutruff
@akutruff
Jun 29 2017 17:03
I pulled that line from ActorRefProvider Init()
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:04
so the motivation behind this
var props = Props.Create(() => new SystemGuardianActor(userGuardian), _systemGuardianStrategy);
versus what we had before
var props = Props.Create<SystemGuardianActor>(userGuardian).WithSupervisorStrategy(_systemGuardianStrategy);
Andy Kutruff
@akutruff
Jun 29 2017 17:06
Yep, just like DI systems
Been here.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:06
is that I can't compile time check that implementation no. 2 is valid
I have to trust that I entered the constructor arguments for SystemGuardianActor in the correct order
and with the right types
Andy Kutruff
@akutruff
Jun 29 2017 17:07
Totally understand this pattern. Don't know if it's changed, but if you're doing it often, you end up getting a big perf hit unless you cache the props
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:07
we do cache it inside the ActorCell of each actor
Andy Kutruff
@akutruff
Jun 29 2017 17:07
(or whatever you're using the epxresion for)
the actual props object?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:07
yep
it's needed for restarts
Andy Kutruff
@akutruff
Jun 29 2017 17:07
but won't I be calling Props.
.Create all the time?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:08
nah, because the props value you get back
already has the data it extracted from this lambda
it never needs to look at that function again
Andy Kutruff
@akutruff
Jun 29 2017 17:08
So I actually hold onto the props object for the next time I create the actor?
In other words, I cache it, not the system
It becomes my factory of sorts
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:09
you pass that Props object into Context.ActorOf
and yep, it's a factory
Context.ActorOf is the factory
Props is the formula
tells the factory what it should produce
Andy Kutruff
@akutruff
Jun 29 2017 17:10
Yeah, but I should call createprops a handfull of times, and keep reusing the same props object after the call of CreateProps
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:10
yep
typically you don't need to call Props.Create again if the constructor arguments for those actors don't change
so if you create a pool router with 10 routees
Andy Kutruff
@akutruff
Jun 29 2017 17:10
Yeah, so like DI Expression tree stuff - expensive once. The problem is that most people think that you can use expressions in tight loops
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:11
it uses the same props to create all 10
what I'm thinking is going on here is a bug actually... trying to get Linqpad to add a reference for me so I can check
Andy Kutruff
@akutruff
Jun 29 2017 17:11
Wait, so if I say system.ActorOf<FooActor>()
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:11
that code checking for a unary expression should not be kicking in
Andy Kutruff
@akutruff
Jun 29 2017 17:12
it hides that... so is there a Dictionary<Type, Props>?
I'm a bit worried that expression trees are getting generated often for the main function
*mainline methodes
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:12
under the hood it just calls Props.Create
Andy Kutruff
@akutruff
Jun 29 2017 17:13
That's what I'm worried about. This is so subtle. If you look at the git issue I plopped, you'll see the ILSPY
The cost is in the callling function
Expression<Func<FooActor>> expression = () => new FooActor();
That's like 5 allocations every time that line is executed
even before you actually use the expression
Totally fine and useful like closures, but scary in tight loops.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:15
if you're using Props.Create repeatedly
you'll incur that cost
however
Props itself
does not need to do that
btw, so I was able to verify that the expression.compile call doesn't get called
but the GetArguments call seems to be the problem
since I guess that compiles it under the hood, right?
Andy Kutruff
@akutruff
Jun 29 2017 17:16
How is Compile in that callstack?
(the one I sent)
GetArguments seems to call it
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:17
yeah must be
class MyActor : ReceiveActor
{
}

void Main()
{

    Expression<Func<MyActor>> factory = () => new MyActor();

    Console.WriteLine(factory.Body is UnaryExpression);
}
just ran that in Linqpad
evaluates to false
so for supporting Unity3d
if we rewrote that line to be
Andy Kutruff
@akutruff
Jun 29 2017 17:18
Oh, but CreateSystemGuardian has args
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:19
var props = Props.Create<SystemGuardianActor>(userGuardian).WithSupervisorStrategy(_systemGuardianStrategy);
that'd avoid the problem
never goes near the expression compiler
lets the human provide the CTOR arguments
Andy Kutruff
@akutruff
Jun 29 2017 17:19
Yeah, so you're in fluent interface world, which I totally understand why you wanted compile time checks
much less scary for AOT
eh, it's more like we have to support a few different audiences
Andy Kutruff
@akutruff
Jun 29 2017 17:20
So that then puts a constraint on Akka proper to not use Expression<> based stuff
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:21
in most contexts users want something that they can't use to shoot themselves in the foot
Andy Kutruff
@akutruff
Jun 29 2017 17:21
Yeah, I get it. The Expression based props is much cooler and safer and would love to use it. : /
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:21
hence why that syntax is so popular
but in others
Andy Kutruff
@akutruff
Jun 29 2017 17:21
I would love to use expressions in other places too, but alas
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:21
performance might be more important
Andy Kutruff
@akutruff
Jun 29 2017 17:22
Yeah, so it comes down to the project itself deciding on whether to constrain the internals
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:22
well the Akka.NET team is experienced enough now, IMHO, to start using the latter syntax for all of its internal Props calls
oh man
even better idea
back to Roslyn
we could just have an analyzer rewrite former calls to the latter at compile-time
.... I thiiiiiiiiink
Andy Kutruff
@akutruff
Jun 29 2017 17:23
How much would that add to my compile wall clock times?
I'm abandoning compile time code gen, and aspects because our compile times started approaching 30 seconds and I was dying inside
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:24
lol
30 second compile times
that would be lovely
doing a full rebuild on the build server from the .NET CLI
is a minutes-long exercise
Andy Kutruff
@akutruff
Jun 29 2017 17:25
My rule, is if I have enough time to open reddit while I'm compiling it's too long
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:25
doing it in VS 2015 wasn't too bad
it's rough in 2017 though
Andy Kutruff
@akutruff
Jun 29 2017 17:25
Sure sure. IL2CPP for any empty project is like a minute+ I'm talking about when I'm just writing a feature
Also, a compile-time tool dependency increases barrier to entry
Nuget could make it much easier, but it may end up having to be a VS extension?
I like the idea of having an analyzer in the IDE though.
A lot.
That tool would be beneficial to every unity developer regardless of akka
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:28
IMHO
Andy Kutruff
@akutruff
Jun 29 2017 17:28
AOT errors can happen even when you're being watchful
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:28
I think an AOT analyzer would be super helpful
would give library authors a chance to see what' sup
but anyway, we'll work on trying to support you and the Unity community
if you can outline the areas where the problems are
we'll think about how we can tackle those
Andy Kutruff
@akutruff
Jun 29 2017 17:31
So right now, I have that crossroads of facing a new library that needs changes in order to use it... If it's a case of simply finding the props calls and converting to the fluent API, then I can justify the time. The other question
are generic interfaces used heavily?
That's usually much harder to change
Sorry, generic virtuals
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:42
let me look real fast... not as far as I know
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.tt(53):        public virtual UnzipWith<TIn, <#= typeParams #>> Create(Func<TIn, Tuple<<#= typeParams #>>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(42):        public virtual UnzipWith<TIn, TOut0, TOut1> Create(Func<TIn, Tuple<TOut0, TOut1>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(61):        public virtual UnzipWith<TIn, TOut0, TOut1, TOut2> Create(Func<TIn, Tuple<TOut0, TOut1, TOut2>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(81):        public virtual UnzipWith<TIn, TOut0, TOut1, TOut2, TOut3> Create(Func<TIn, Tuple<TOut0, TOut1, TOut2, TOut3>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(102):        public virtual UnzipWith<TIn, TOut0, TOut1, TOut2, TOut3, TOut4> Create(Func<TIn, Tuple<TOut0, TOut1, TOut2, TOut3, TOut4>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(124):        public virtual UnzipWith<TIn, TOut0, TOut1, TOut2, TOut3, TOut4, TOut5> Create(Func<TIn, Tuple<TOut0, TOut1, TOut2, TOut3, TOut4, TOut5>> unzipper)
  D:\olympus\akka.net\src\core\Akka.Streams\CodeGen\Dsl\UnzipWith.cs(147):        public virtual UnzipWith<TIn, TOut0, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6> Create(Func<TIn, Tuple<TOut0, TOut1, TOut2, TOut3, TOut4, TOut5, TOut6>> unzipper)
Akka.Streams does
otherwise no
none of the other modules do
IMHO if it's just changing Props on some internal actors inside Akka
that's probably not too hard
we don't have that many system actors in Akka core
just the logging actors and the guardians
Andy Kutruff
@akutruff
Jun 29 2017 17:46
Sweet, thanks for checking. Trying to compile akka from main branch and see if I can make these changes
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:46
in Akka.Remote we have all of the endpoint actors
and Akka.Persistence we have the journals
but you're talking under a dozen actor types for each of those modules
Andy Kutruff
@akutruff
Jun 29 2017 17:47
"Your project.json doesn't have a runtimes section. You should add '"runtimes": { "win": { } }' to your project.json and then re-run NuGet restore."
VS 2017.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:48
turn it on and off again
only half-kidding
Andy Kutruff
@akutruff
Jun 29 2017 17:48
heh, huh?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:48
we get weird shit with VS2017 all the time
I have no idea why
although @heynickc would be the guy to ask about that issue :p
Nick Chamberlain
@heynickc
Jun 29 2017 17:53
sometimes I've had to search for "project.json" files in the project and if they show up, they are sometimes in the /obj folders in the individual project, I don't know where they come from. but it happens if I switch between our dev branch to our v1.3 .net core branch, it leaves dirtiness around in the build output folders
if you get rid of that file, or clear out the obj folder it might help
Andy Kutruff
@akutruff
Jun 29 2017 17:54
I'm actually starting a fresh clone directly from dev. Is that 1.2.2?
(I was in 1.3)
Cool, going to a fresh dev and akka.sln compiled.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:56
yeah 1.2.2 is the latest
just published it yesterday
Andy Kutruff
@akutruff
Jun 29 2017 17:56
in dev branch though, not master, right?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:57
1.3 is our giant .NET Core branch
yeah, dev branch
Andy Kutruff
@akutruff
Jun 29 2017 17:57
cool
Aaron Stannard
@Aaronontheweb
Jun 29 2017 17:57
although dev and master are equal right now since we just released
normally not the case
Andy Kutruff
@akutruff
Jun 29 2017 18:12
That one line change worked! UntypedActor running on background thread.
No AOT issues
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:12
nice
you should also trying making a logging call
if that works without an AOT issue then the entire Akka core module should be certifiable on Unity3D (minus Akka.IO maybe)
Andy Kutruff
@akutruff
Jun 29 2017 18:16
Do you have a one liner for me?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:17
Context.GetLogger().Debug("boom!");
I think
yep, that'll do it
had to double check on the method name
but if you do that inside the actor itself that should do it
Andy Kutruff
@akutruff
Jun 29 2017 18:19
'IUntypedActorContext' does not contain a definition for 'GetLogger' and no extension method 'GetLogger'
I'm only refernecing the Actor csproj
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:19
might need to import a namespace
Akka.Event
Andy Kutruff
@akutruff
Jun 29 2017 18:19
That's the stuff. Checking now...
Well, the line of code is executing, but I can't get at stdout with Unity... is there a logging callback or something that I can use?
Just want to make sure that it's doing it's thing
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:24
Context.System.EventStream.Subscribe(typeof(LogEvent), Self)
you can receive the event you logged that way
Andy Kutruff
@akutruff
Jun 29 2017 18:24
perfect. checking
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:24
if it's not crashing it's working IMHO
thing would have barfed up an AOT error at startup probably
since we start the STDOUT logger immediately
Andy Kutruff
@akutruff
Jun 29 2017 18:29
I just don't trust unity until I see the side effect of any code.
  public class ChatClient : UntypedActor
    {
        public int NumberOfChatsReceived;
        private bool _isSubscribed;
        public ChatClient()
        {

        }

        protected override void OnReceive(object message)
        {
            if (!_isSubscribed)
            {
                _isSubscribed = true;
                Context.System.EventStream.Subscribe<LogEvent>(Self);
            }

            if (message is PostChatCommand)
            {
                PostChatCommand postChatCommand = (PostChatCommand)message;
                NumberOfChatsReceived++;
                ChatClientProgram.PutInHistory(postChatCommand.ChatMessage + " " + NumberOfChatsReceived);
                Context.GetLogger().Debug("boom!");
            }
            else
            {
                ChatClientProgram.PutInHistory("Logging working");
            }

        }
    }
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:30
see any "logging working" ?
Andy Kutruff
@akutruff
Jun 29 2017 18:30
Not yet
I assumed I should do the subscribe in the constructor
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:31
I usually do it in PreStart
one of the lifecycle methods
Andy Kutruff
@akutruff
Jun 29 2017 18:31
I had to use the generic subscribe, there wasn't an overload with Type
    public class ChatClient : UntypedActor
    {
        public int NumberOfChatsReceived;

        protected override void PreStart()
        {
            Context.System.EventStream.Subscribe<LogEvent>(Self);
        }

        protected override void OnReceive(object message)
        {

            if (message is PostChatCommand)
            {
                PostChatCommand postChatCommand = (PostChatCommand)message;
                NumberOfChatsReceived++;
                ChatClientProgram.PutInHistory(postChatCommand.ChatMessage + " " + NumberOfChatsReceived);
                Context.GetLogger().Debug("boom!");
            }
            else
            {
                ChatClientProgram.PutInHistory("Logging working");
            }

        }
    }
Not working either
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:33
hmmm
if an async part of Akka.NET failed AOT
would that just silently fail in the background if an actor caught the exception?
Andy Kutruff
@akutruff
Jun 29 2017 18:35
yep. Is there a way to force single threaded?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:35
we have the synchronized dispatcher in the Akka.TestKit
Andy Kutruff
@akutruff
Jun 29 2017 18:35
I actually had to run this all synchronous to find the error
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:35
but that'd create a stack overflow exception on a busy enough workload
Andy Kutruff
@akutruff
Jun 29 2017 18:35
I'll switch off the threadpool again.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:36
since it uses tail recursion :p
let me check that BugLogging class...
Andy Kutruff
@akutruff
Jun 29 2017 18:37
this actually isn't working even without aot
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:37
ah
must be a code issue then
let me finish up what I was doing in LinqPad
.... might be that we actually publish a different msg to the EventStream
other than LogEvent
yeah that was it
whoops
Andy Kutruff
@akutruff
Jun 29 2017 18:42
Filling my code with lies.
The default logger uses LogEvent
This code is terribly clean, btw
well done
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:45
thank the original JVM Akka team - they did most of the hard work there
although we've done a good job keeping it clean on the CLR too
ok, this is driving me nuts
I've written custom loggers before
what is the damn class I have to use to subscribe !!!
Andy Kutruff
@akutruff
Jun 29 2017 18:46
Is logging turned on be default?
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:46
omfg... I'm an idiot
akka.loglevel = info by default
debug messages won't get logged
Lealand Vettleson
@spankr
Jun 29 2017 18:46
yup
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:46
I was right the first time
it's LogEvent
lol
I just needed to change the call to Info and it worked
class MyActor : UntypedActor
{
    private readonly ILoggingAdapter _log = Context.GetLogger();

    protected override void PreStart()
    {
        Context.System.EventStream.Subscribe(Self, typeof(LogEvent));
    }

    protected override void OnReceive(object message)
    {
        switch (message)
        {
            case "hit":
                _log.Info("foo");
                break;
            case LogEvent l:
                Console.WriteLine(l.Message);
                Self.Tell("shutdown");
                break;
            case "shutdown":
                Context.System.Terminate();
                break;
        }
    }
}

void Main()
{
    using (var a = ActorSystem.Create("mysys")) {
        a.ActorOf<MyActor>().Tell("hit");
        a.WhenTerminated.Wait();
    }
}
that creates a pretty funny message loop when the app recursively tries to terminate itself
Lealand Vettleson
@spankr
Jun 29 2017 18:47
I noticed that in my unit tests when I was expecting them to get logged. I had to modify my test constructor for "loglevel=DEBUG"
that's a pretty cool actor
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:48
fancy C# 7 syntax
Andy Kutruff
@akutruff
Jun 29 2017 18:49
Sweet. Working in editor checking AOT
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:49
@spankr we usually have to leave debug logging off in our specs on the project
we produce an incredible amount of logs on each build
have to try to trim it down until we know there's a bug
Lealand Vettleson
@spankr
Jun 29 2017 18:50
oh, I understand the reasons for it
that and after I figured out why I wasn't seeing the debug messages, it occurred to me that testing that a debug log message was fired is a bit of a code smell
Andy Kutruff
@akutruff
Jun 29 2017 18:50
:sparkle:
:sparkles:
Worked
Lealand Vettleson
@spankr
Jun 29 2017 18:51
:thumbsup:
Andy Kutruff
@akutruff
Jun 29 2017 18:52
Thanks for help. Will report back with remoting results when I get it working.
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:52
sounds good
Andy Kutruff
@akutruff
Jun 29 2017 18:52
This is officially the least painful Unity AOT port in the last 5 years
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:52
look forward to getting a PR
@spankr we're sitting at about 100 GB worth of logs
and I think we rotate them regularly
and 100 GB worth of artifacts for Akka.NET
some of those artifacts are NuGet packages and documentation
but most are MNTR logs and NBench reports
Lealand Vettleson
@spankr
Jun 29 2017 18:54
:O
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:55
I think the retention period is 90 days
or something
I allocated half a terrabyte on that server 2.5 years ago
still using less than half of it
Lealand Vettleson
@spankr
Jun 29 2017 18:56
any larger and you may want to contact this place for storage rates: https://en.wikipedia.org/wiki/Utah_Data_Center
Aaron Stannard
@Aaronontheweb
Jun 29 2017 18:56
I'll worry about it when log growth exceeds what we claim back from artifact expiration :p
Lealand Vettleson
@spankr
Jun 29 2017 18:57
hah!
Andy Kutruff
@akutruff
Jun 29 2017 20:13
Well, IL2CPP shit itself dealing with Exception Filters, and it's hanging on basic remoting.
Andy Kutruff
@akutruff
Jun 29 2017 20:34
Hmm. is there a catch all for any background exceptions?
Andy Kutruff
@akutruff
Jun 29 2017 20:45
Oh, yikes... So remoting requires both apps to open and listen on tcp ports?
Jesse Connor
@jesseconnr
Jun 29 2017 21:07
So trying to work out the flow of data for an app where data is edited by multiple users at the same time, this is what I've got so far based on what I've read. Looking for potential issues I might not be seeing. - https://gist.github.com/jesseconnr/a5ccce129229fad88feab2370772bf1d
Lealand Vettleson
@spankr
Jun 29 2017 21:09
in our Akka.IO tcp communication, we're seeing 0 byte messages coming out of that. Is there internal keepalive logic in the tcp actor by any chance?
(I can go dig around if no one knows off the top of their head)
Aaron Stannard
@Aaronontheweb
Jun 29 2017 21:30
@akutruff yes it does - it's mostly designed for server-side stuff
Akka.IO, on the other hand, does not
and from a security standpoint, Akka.IO will be a better call for client-server stuff
@spankr oh man
on that count, I have no idea
and we're about to pull in a bunch of changes that rewrite all of that
currently staged here
akkadotnet/akka.net#2683
@akutruff speaking from personal experience, I'm using Akka.IO in one of our products here: https://cmd.petabridge.com/
Aaron Stannard
@Aaronontheweb
Jun 29 2017 21:35
works pretty well - only real catch is you have to handle:
  1. Serialization
  2. Partial reads
  3. Message framing
no 2 is usually the one that trips people up who've never worked with sockets before
Akka.IO abstracts over the socket and connection lifecycle stuff itself
but your actors who are consuming Akka.IO bits are receiving messages that contain ByteString objects
and that's what has to be combined
in the event of a partial read
now if that stuff sounds like too much overhead, you can use DotNetty directly - which is what powers Akka.Remote: https://github.com/azure/dotnetty
DotNetty has some better OOB tooling for handling that type of stuff, but it's a bit of a bear to learn on its own
at first, anyway
DotNetty is used in the infrastructure that powers the Windows Azure IOT hub
so it's designed to be very efficient on low power devices
which fits your use case
but, going back to Akka.IO
Aaron Stannard
@Aaronontheweb
Jun 29 2017 21:40
I had a much better experience using that in our CLI tool
was super easy to work with
and easy to test
Jesse Connor
@jesseconnr
Jun 29 2017 23:09
A hololens and an app with voice controls to quickly build massive workflows would go a long way in developing message flow through actors. :D
Gregorius Soedharmo
@Arkatufus
Jun 29 2017 23:45
errr...?