示例#1
0
        public Process(string name, ActorSystem actorSystem, IActor actor, ActorOptions options)
            : base(-1, -1)
        {
            _name = name;

            _actor       = actor;
            _actorSystem = actorSystem;

            _pid = new Pid(this);
            _ctx = new Context(this);

            _errorHandler = (options.ErrorHandler ?? actorSystem.Options.ErrorHandler) ?? DefaultErrorHandler.Instance;

            var requestTimeoutMSec = GetRequestTimeoutMSec(actorSystem, options);

            _requestTimeoutMSec = !requestTimeoutMSec.HasValue ? (int?)null :
                                  Math.Min(Math.Max(-1, requestTimeoutMSec.Value), Constants.MaxRequestTimeoutMSec);

            SetSequentialInvokeLimit(GetSequentialInvokeLimit(actorSystem, options));

            if (options.InitialContextData != null)
            {
                foreach (var kv in options.InitialContextData)
                {
                    _ctx.SetData(kv.Key, kv.Value);
                }
            }

            _processRegistery.TryAdd(_pid, this);
        }
示例#2
0
        public Pid From(ActorOptions options)
        {
            ThrowIfDisposed();

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (IsRemote(options))
            {
                return(FromRemote(options));
            }

            Type actorType = null;

            var actor = options.Actor;

            if (actor == null)
            {
                actorType = options.ActorType;
            }

            if (actor == null && actorType == null)
            {
                throw new ArgumentNullException(nameof(options.Actor));
            }

            return(GetOrAdd(options, actor, actorType));
        }
示例#3
0
        private int GetSequentialInvokeLimit(ActorOptions options)
        {
            var result = options.SequentialInvokeLimit;

            if (result < 1)
            {
                result = Options.SequentialInvokeLimit;
            }

            return(result);
        }
示例#4
0
        private int?GetRequestTimeoutMSec(ActorOptions options)
        {
            var result = options.RequestTimeoutMSec;

            if (!result.HasValue || result == -1)
            {
                result = Options.RequestTimeoutMSec;
            }

            return(result);
        }
示例#5
0
        public Pid FromActor(IActor actor, ActorOptions options = null)
        {
            ThrowIfDisposed();

            if (actor == null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            return(GetOrAdd(options, actor, actor.GetType()));
        }
示例#6
0
        public Pid FromRemote(ActorOptions options)
        {
            ThrowIfDisposed();

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var remoteActorSystem = options.RemoteActorSystem?.Trim();

            if (String.IsNullOrEmpty(remoteActorSystem))
            {
                throw new ArgumentNullException(nameof(options.RemoteActorSystem));
            }

            var remoteActor = options.Name?.Trim();

            if (String.IsNullOrEmpty(remoteActor))
            {
                throw new ArgumentNullException(nameof(options.Name));
            }

            var isNew = false;

            var actorType   = typeof(RemoteProcess);
            var processType = ProcessType.Remote;

            var registry = _processRegistery.GetOrAdd($"remote://{remoteActorSystem}/{remoteActor}",
                                                      (an) =>
            {
                isNew = true;
                var p = new RemoteProcess(name: remoteActor,
                                          actorSystem: this,
                                          remoteAddress: new RemoteAddress(options.EndPoint, remoteActorSystem, remoteActor),
                                          options: options);

                return(new ProcessRegistery {
                    Process = p,
                    ActorType = actorType,
                    ProcessType = processType
                });
            });

            if (!isNew &&
                (registry.ProcessType != processType) || (registry.ActorType != actorType))
            {
                throw new Exception(Errors.ActorWithNameOfDifferentTypeAlreadyExists);
            }

            return(registry.Process.Pid);
        }
示例#7
0
        private static void RunSystem()
        {
            var systemOptions = ActorSystemOptions
                                .UsingName("system-1")
                                .UsingErrorHandler(
                (actorSys, error) => { Console.WriteLine(error); },
                (actorSys, process, msg, error) => { Console.WriteLine(error); });

            var actorSystem = ActorSystem.GetOrAdd(systemOptions);

            var actorOptions = ActorOptions
                               .UsingName("system-1-actor-1");

            var Completed = Task.FromResult(0);

            var sw = new Stopwatch();

            var pid = actorSystem.FromFunction((ctx, message) =>
            {
                var count = Interlocked.Increment(ref counter);

                if (count == 1)
                {
                    sw.Restart();
                }
                else
                {
                    if (count % 1000 == 0)
                    {
                        Console.WriteLine(count);
                    }

                    if (count == loop)
                    {
                        Interlocked.Exchange(ref counter, 0);

                        sw.Stop();
                        Console.WriteLine("Ellapsed time: " + sw.ElapsedMilliseconds);
                        Console.WriteLine("Concurrency: " + (loop * 1000 / sw.ElapsedMilliseconds) + " call per sec");
                    }
                }

                if (message.MessageType == MessageType.FutureMessage)
                {
                    ctx.RespondTo(message, "world " + count.ToString("000"));
                }

                return(Completed);
            },
                                               actorOptions);
        }
示例#8
0
        private Pid GetOrAdd(ActorOptions options, IActor actor, Type actorType)
        {
            options = (options ?? ActorOptions.Default);

            if (actor != null)
            {
                actorType = actor.GetType();
            }

            var actorName = options.Name?.Trim();

            if (String.IsNullOrEmpty(actorName))
            {
                actorName = actorType.ToString();
            }

            var isNew       = false;
            var processType = ProcessType.Class;

            var registry = _processRegistery.GetOrAdd(actorName,
                                                      (an) =>
            {
                isNew = true;

                var p = new Process(name: an,
                                    actorSystem: this,
                                    actor: actor ?? (IActor)Activator.CreateInstance(actorType),
                                    options: options);

                return(new ProcessRegistery {
                    Process = p,
                    ActorType = actorType,
                    ProcessType = processType
                });
            });

            if (!isNew &&
                ((registry.ProcessType != processType) || (registry.ActorType != actorType)))
            {
                throw new Exception(Errors.ActorWithNameOfDifferentTypeAlreadyExists);
            }

            return(registry.Process.Pid);
        }
示例#9
0
        public Pid FromFunction(Func <IContext, IMessage, Task> receiveFunc, ActorOptions options = null)
        {
            ThrowIfDisposed();

            if (receiveFunc == null)
            {
                throw new ArgumentNullException(nameof(receiveFunc));
            }

            options = (options ?? ActorOptions.Default);

            var actorName = options.Name?.Trim();

            if (String.IsNullOrEmpty(actorName))
            {
                actorName = AnonymousNameGenerator.Next();
            }

            var isNew = false;

            var actorType   = typeof(FunctionCallProcess);
            var processType = ProcessType.Function;

            var registry = _processRegistery.GetOrAdd(actorName,
                                                      (an) =>
            {
                isNew = true;

                var p = new FunctionCallProcess(name: actorName,
                                                actorSystem: this,
                                                function: receiveFunc,
                                                options: options);

                return(new ProcessRegistery {
                    Process = p,
                    ActorType = actorType,
                    ProcessType = processType
                });
            });

            if (!isNew)
            {
                if (registry.ProcessType != processType)
                {
                    throw new Exception(Errors.ActorWithNameOfDifferentTypeAlreadyExists);
                }

                var fp = registry.Process as FunctionCallProcess;
                if (fp == null)
                {
                    throw new Exception(Errors.ActorWithNameOfDifferentTypeAlreadyExists);
                }

                if (fp.ReceiveFunc != receiveFunc)
                {
                    throw new Exception(Errors.ActorAlreadyExsists);
                }
            }

            return(registry.Process.Pid);
        }
示例#10
0
 public Pid FromType <T>(ActorOptions options = null)
     where T : class, IActor, new()
 {
     ThrowIfDisposed();
     return(GetOrAdd(options, null, typeof(T)));
 }
示例#11
0
 private bool IsRemote(ActorOptions options)
 {
     return((options?.EndPoint != null) &&
            !String.IsNullOrEmpty(options?.RemoteActorSystem?.Trim()));
 }