Esempio 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;

            context.ReenterAfter(MemberList.GetMemberAsync(name, kind), address =>
            {
                if (string.IsNullOrEmpty(address.Result))
                {
                    context.Respond(new PidCacheResponse(null, ResponseStatusCode.Unavailable));
                    return(Actor.Done);
                }

                var remotePid = Partition.PartitionForKind(address.Result, kind);
                var req       = new ActorPidRequest
                {
                    Kind = kind,
                    Name = name
                };
                var reqTask = remotePid.RequestAsync <ActorPidResponse>(req);
                context.ReenterAfter(reqTask, t =>
                {
                    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;
                        if (_reverseCacheByMemberAddress.ContainsKey(res.Pid.Address))
                        {
                            _reverseCacheByMemberAddress[res.Pid.Address].Add(key);
                        }
                        else
                        {
                            _reverseCacheByMemberAddress[res.Pid.Address] = new HashSet <string> {
                                key
                            }
                        };

                        context.Watch(res.Pid);
                        context.Respond(new PidCacheResponse(res.Pid, status));
                        break;

                    default:
                        context.Respond(new PidCacheResponse(res.Pid, status));
                        break;
                    }
                    return(Actor.Done);
                });
                return(Actor.Done);
            });
        }
Esempio n. 2
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);
            });
        }