Exemplo n.º 1
0
        private void GetPid(IContext context, PidCacheRequest msg)
        {
            if (_cache.TryGetValue(msg.Name, out var pid))
            {
                //found the pid, replied, exit
                context.Respond(new PidCacheResponse(pid, ResponseStatusCode.OK));
                return;
            }

            var name = msg.Name;
            var kind = msg.Kind;

            var address = MemberList.GetPartition(name, kind);

            if (string.IsNullOrEmpty(address))
            {
                context.Respond(new PidCacheResponse(null, ResponseStatusCode.Unavailable));
                return;
            }

            var remotePid = Partition.PartitionForKind(address, kind);
            var req       = new ActorPidRequest
            {
                Kind = kind,
                Name = name
            };

            var reqTask = remotePid.RequestAsync <ActorPidResponse>(req, Cluster.cfg.TimeoutTimespan);

            context.ReenterAfter(reqTask, t =>
            {
                if (t.Exception != null)
                {
                    if (t.Exception.InnerException is TimeoutException)
                    {
                        //Timeout
                        context.Respond(new PidCacheResponse(null, ResponseStatusCode.Timeout));
                        return(Actor.Done);
                    }
                    else
                    {
                        //Other errors, let it throw
                        context.Respond(new PidCacheResponse(null, ResponseStatusCode.Error));
                    }
                }

                var res    = t.Result;
                var status = (ResponseStatusCode)res.StatusCode;
                switch (status)
                {
                case ResponseStatusCode.OK:
                    var key            = res.Pid.ToShortString();
                    _cache[name]       = res.Pid;
                    _reverseCache[key] = name;
                    context.Watch(res.Pid);
                    context.Respond(new PidCacheResponse(res.Pid, status));
                    break;

                default:
                    context.Respond(new PidCacheResponse(res.Pid, status));
                    break;
                }
                return(Actor.Done);
            });
        }