These are chat archives for akkadotnet/akka.net

18th
Jul 2016
Arsene T. Gandote
@Tochemey
Jul 18 2016 06:27
@Horusiath Thank you. The proposed solution works as expected.
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 07:08
@themdrnsamurai it depends on how are you going to access the data inside DocumentDB - if you want to use actors as a form of smart cache, then they should either have a full authority over writing any new data to docdb or have a some sort of scheduled task that will trigger the state refresh within some time intervals.
Samurai Ken
@themdrnsamurai
Jul 18 2016 07:12

@Horusiath - thanks, yeah, it sems pretty clear ideally the actor should be the sole interface to the underlying DB record. And that is with me. I just wont be able to seel converting our date purely to live within the actor state persistence store but I can se;; this.

The idea is that if, in the future, we need to interface with the data in some other way or move to another technology the data is not deeply tied to the actor implementation chosen.

Bartosz Sypytkowski
@Horusiath
Jul 18 2016 07:15
you could create your own "record" object, and just bind its methods to akka actor receiviers
so actor will work as a shell around your "record" - it's pretty limiting the possibilities of particular actor model, but it's the most framework agnostic approach
Arsene T. Gandote
@Tochemey
Jul 18 2016 07:52
Hello how do I define an Actor state that will be available during the lifetime of the actor.
Samurai Ken
@themdrnsamurai
Jul 18 2016 07:53
@Horusiath I hear you on that being limiting, I am sort of hoping to avoid that (having the DocumentDB record actually act as the store for the Actor directly) it just seems liek that shoudl be wrong somehow :)
Bart de Boer
@boekabart
Jul 18 2016 07:55
@Tochemey please elaborate
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 07:57
@Tochemey actor's fields and properties is what we call actor state
Arsene T. Gandote
@Tochemey
Jul 18 2016 07:59

This is the code:

public class ModulesActor : ReceiveActor
    {
        private Dictionary<string, Tuple<Props, ModuleState>> _moduleRecipes;

        public ModulesActor()
        {
            Ready();
        }

        public override void AroundPreStart()
        {
            _moduleRecipes = new Dictionary<string, Tuple<Props, ModuleState>>();
        }

        public override void AroundPostStop()
        {
            _moduleRecipes = null;
        }

        protected void Ready()
        {
            Receive<LoadModules>(modules => Load());
            Receive<ModulesLoaded>(c =>
            {
                _moduleRecipes = c.Modules;
            });

            Receive<GetModuleMeta>(whois =>
            {
                Sender.Tell(GetModuleMeta(whois.ModuleName));
            });

            Receive<CheckModuleState>(state =>
            {
                Sender.Tell(GetModuleState(state.ModuleName));
            });
        }

        private ModuleState GetModuleState(string moduleName)
        {
            if (!_moduleRecipes.ContainsKey(moduleName))
                return ModuleState.NOT_IMPLEMENTED;
            return _moduleRecipes[moduleName].Item2;
        }

        protected override SupervisorStrategy SupervisorStrategy()
        {
            return new OneForOneStrategy(1,
                // maxNumberOfRetries
                TimeSpan.FromSeconds(30),
                // withinTimeRange

                exception => // localOnlyDecider
                {
                    //Error that we cannot recover from, stop the failing actor
                    if (exception is NotSupportedException) return Directive.Stop;

                    // Error related to configuration setting
                    if (exception is ConfigurationErrorsException) {
                        return Directive.Escalate;
                    }

                    //In all other cases, just stop the failing actor
                    return Directive.Stop;
                });
        }

        private ModuleMeta GetModuleMeta(string moduleName)
        {
            if (!_moduleRecipes.ContainsKey(moduleName)) return null;
            var moduleMeta = new ModuleMeta(_moduleRecipes[moduleName].Item1,
                _moduleRecipes[moduleName].Item2);
            return moduleMeta;
        }

        private static void Load()
        {
            var loader = Context.ActorOf(Props.Create(() => new ModulesLoadingActor()));
            loader.Forward(new LoadModules());
        }
    }

This is the test I am running:

        public void ModulesLoaderActorShouldReturnALoadedModule()
        {
            ActorSystemRefs.ActorSystem = Sys;
            var actorSystem = ActorSystemRefs.ActorSystem;
            var moduleManager = actorSystem.ActorOf(Props.Create(() => new ModulesActor()));
            moduleManager.Tell(new LoadModules());
            var result = ExpectMsg<ModulesLoaded>();
            Assert.NotNull(result);

            moduleManager.Tell(new CheckModuleState("mtn-gh"));
            var moduleMeta = ExpectMsg<ModuleMeta>();
            Assert.NotNull(moduleMeta);
            Assert.True(moduleMeta.State == ModuleState.ONLINE);
        }

The issue I am facing is that the moduleMeta.State does not return the expected value. The first assertion works smoothly.

Bart de Boer
@boekabart
Jul 18 2016 08:01
Your manager never gets ModulesLoaded, is I think your root casue
because you forward the LoadModules, the response goes directly to the external requester. in this case, TestActor
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:03
@boekabart Any solution?
Bart de Boer
@boekabart
Jul 18 2016 08:03
Tell instead of forward.
(note that your 'outer' actor won't get confirmation directly anymore)
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:04
@boekabart The reason I used forward is that I do not want to pass the SenderRef into the message.
@boekabart and the Ask-PipeTo is not too recommended in Actors.
Bart de Boer
@boekabart
Jul 18 2016 08:05
yes, but you do want to the loader to respond to the manager, right?
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:05
@boekabart Yes
Bart de Boer
@boekabart
Jul 18 2016 08:06
separate your 'outer contract' from your 'inner contract'
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:06
@boekabart How?
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:06
@Tochemey if ModulesLoaded is addresses specifically to manager, you don't need to check for it using ExpectMsg
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:06
Ok
However It still did not work
Bart de Boer
@boekabart
Jul 18 2016 08:08
@Tochemey try drawing a sequence diagram with 'outside requester', 'manager' and 'loader' as actors
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:10
@Tochemey you either can use Ask (which is not recommended, because it's slow) or change behavior after LoadModules call
Bart de Boer
@boekabart
Jul 18 2016 08:10
Ask won't work, because the manager has to update its state in the continuation (recipes)
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:10
I'll send an example in a sec
@boekabart I was talking about using Ask inside ReceiveAsync
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:38
@Horusiath So please how do I then proceed with the test code because even the code change I am now getting ModuleLoaded message instead of the expected result: This the new test code:
            ActorSystemRefs.ActorSystem = Sys;
            var actorSystem = ActorSystemRefs.ActorSystem;
            var moduleManager = actorSystem.ActorOf(Props.Create(() => new ModulesActor()));
            moduleManager.Tell(new LoadModules());
            moduleManager.Tell(new CheckModuleState("mtn-gh"));
            var moduleMeta = ExpectMsg<ModuleMeta>();
            Assert.NotNull(moduleMeta);
            Assert.True(moduleMeta.State == ModuleState.ONLINE);
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:40
@Tochemey have you applied changes from my sample gist?
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:44
@Horusiath Yes I have done that exactly.
@Horusiath A mn I am checking something
Still not working
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:47
it looks like you have Forward or Tell(..., Sender) somewhere in your ModulesActor code
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:49
@Horusiath The ModulesActor has a child Actor call ModulesLoader. Its jobs is to load the modules and returns a ModulesLoaded info to the ModulesActors. ModulesActors use forward to communicate to the child.
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:50
why are you using Forward if you need to get reply back to ModulesActor?
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:51
So what do you suggest then?
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:52
just as I've written in the sample, you can use tell and asynchronously wait for the reply
Arsene T. Gandote
@Tochemey
Jul 18 2016 08:55
@Horusiath How I do design the test code then? I have grabbed the architecture.
Should I send Tell(LoadModules) and another Tell(CheckState)?
Bartosz Sypytkowski
@Horusiath
Jul 18 2016 08:57
Test code stays the same:
            moduleManager.Tell(new LoadModules());
            moduleManager.Tell(new CheckModuleState("mtn-gh"));
            var moduleMeta = ExpectMsg<ModuleMeta>();
Garrard Kitchen
@garrardkitchen
Jul 18 2016 10:02
Hi @Aaronontheweb, I wasn't able to get mono working with F# solution in windows environment so not able to tell whether the sockets error is because of mono or akka. Did any of your tyre kicking turn up anything?
Garrard Kitchen
@garrardkitchen
Jul 18 2016 11:24
Hi @Aaronontheweb, I’ve now ruled out F#. Created new sln in win env and all ok but when running on mac, same error.
Garrard Kitchen
@garrardkitchen
Jul 18 2016 11:30
Has anybody had success with using akka cluster (1.1.1) in docker container?
Weston
@ronnyek
Jul 18 2016 15:08
whats new with akka.net in the past couple mo
are the cluster/lighthouse things working a bit more smoothly (eg, so that if lighthouse drops out after nodes discover one another, and come back in, it doesnt leave you with a cluster thats unusable?)
Garrard Kitchen
@garrardkitchen
Jul 18 2016 15:50
@ronnyek cluster yes, can't comment about lighthouse as we don't use it. Before we pushed 1.1 release out we sequenced through a known set of edge cases where we knew our solution would break. Happy to say, it didn't break. Our multi-tenanted solution consists of several windows services and a few IIS sites. We tested the cluster in isolation (1 server) and over multiple servers. All good.
Arjen Smits
@Danthar
Jul 18 2016 15:56
@garrardkitchen thats good to hear.
fouimette
@fouimette
Jul 18 2016 17:11
blob
Ok. I just upgraded to the latest build (using Nuget) and am seeing this error:
Any thoughts?
Ah, dug a little deeper. The Wire ctor is not found. All I did was update the packages.
blob
oops, wrong image
blob
Alex Valuyskiy
@alexvaluyskiy
Jul 18 2016 17:18
@fouimette @rogeralsing working on this problem
fouimette
@fouimette
Jul 18 2016 17:19
Ah, wonderful. Thanks @alexvaluyskiy
Alex Valuyskiy
@alexvaluyskiy
Jul 18 2016 17:19
just use Wire 0.0.6, before he fix it
fouimette
@fouimette
Jul 18 2016 17:19
ok
Changing Wire to 0.0.6 fixed the problem.
Roger Johansson
@rogeralsing
Jul 18 2016 17:30
Found and fixed the problem in Wire
going to upload a new version asap
cc @alexvaluyskiy @fouimette
Roger Johansson
@rogeralsing
Jul 18 2016 17:46
Wire 0.7.1 is on Nuget, probably showing up any second now
wdspider
@wdspider
Jul 18 2016 18:37
Wire 0.7.1 didn't fix the problem...... it's still throwing the same exception that @fouimette posted.

This seems to be the method it's looking for:

Method not found: 'Void Wire.SerializerOptions..ctor(Boolean, System.Collections.Generic.IEnumerable1<Wire.Surrogate>, Boolean, System.Collections.Generic.IEnumerable1<Wire.Converters.ValueSerializerFactory>)'.

Steven Mitcham
@smitcham
Jul 18 2016 19:55
Are there symbol nuget packages getting published, and if so where?
Bart de Boer
@boekabart
Jul 18 2016 20:01
by design yes, sometimes that step fails and they miss. Symbolsource.org
Aaron Stannard
@Aaronontheweb
Jul 18 2016 20:02
@garrardkitchen haven't done any yet
unfortunately :\
fouimette
@fouimette
Jul 18 2016 20:34
@wdspider is correct. I am getting the same error. Reverting back to 0.0.6.