예제 #1
0
        public IEnumerable <T> AskMany <T>(IEnumerable <ProcessId> pids, object message, int take)
        {
            take = Math.Min(take, pids.Count());

            var responses = new List <AskActorRes>();

            using (var handle = new CountdownEvent(take))
            {
                foreach (var pid in pids)
                {
                    var req = new AskActorReq(
                        message,
                        res =>
                    {
                        responses.Add(res);
                        handle.Signal();
                    },
                        pid.SetSystem(SystemName),
                        Self,
                        typeof(T));
                    tell(AskId, req);
                }

                handle.Wait(ActorContext.System(pids.Head()).Settings.Timeout);
            }
            return(responses.Where(r => !r.IsFaulted).Map(r => (T)r.Response));
        }
예제 #2
0
        public object Ask(ProcessId pid, object message, Type returnType, ProcessId sender)
        {
            if (false) //Process.InMessageLoop)
            {
                //return SelfProcess.Actor.ProcessRequest<T>(pid, message);
            }
            else
            {
                var         sessionId = ActorContext.SessionId;
                AskActorRes response  = null;
                using (var handle = new AutoResetEvent(false))
                {
                    var req = new AskActorReq(
                        message,
                        res => {
                        response = res;
                        handle.Set();
                    },
                        pid,
                        sender,
                        returnType
                        );

                    var askItem = GetAskItem();

                    askItem.IfSome(
                        ask =>
                    {
                        var inbox = ask.Inbox as ILocalActorInbox;
                        inbox.Tell(req, sender, sessionId);
                        handle.WaitOne(ActorContext.System(pid).Settings.Timeout);
                    });

                    if (askItem)
                    {
                        if (response == null)
                        {
                            throw new TimeoutException("Request timed out");
                        }
                        else
                        {
                            if (response.IsFaulted)
                            {
                                throw response.Exception;
                            }
                            else
                            {
                                return(response.Response);
                            }
                        }
                    }
                    else
                    {
                        throw new Exception("Ask process doesn't exist");
                    }
                }
            }
        }