Ejemplo n.º 1
0
 public static Map <A, Map <B, Map <C, D> > > AddOrUpdate <A, B, C, D>(this Map <A, Map <B, Map <C, D> > > self, A aKey, B bKey, C cKey, D value) =>
 self.AddOrUpdate(
     aKey,
     bKey,
     c => c.AddOrUpdate(cKey, _ => value, value),
     () => Prelude.Map(Tuple(cKey, value))
     );
Ejemplo n.º 2
0
 public static Map <A, Map <B, Map <C, D> > > AddOrUpdate <A, B, C, D>(this Map <A, Map <B, Map <C, D> > > self, A aKey, B bKey, C cKey, Func <D, D> Some, Func <D> None) =>
 self.AddOrUpdate(
     aKey,
     bKey,
     c => c.AddOrUpdate(cKey, Some, None),
     () => Prelude.Map(Tuple(cKey, None()))
     );
Ejemplo n.º 3
0
 /// <summary>
 /// Gains a child process
 /// </summary>
 public Unit LinkChild(ActorItem item)
 {
     lock (sync)
     {
         children = children.AddOrUpdate(item.Actor.Id.GetName().Value, item);
     }
     return(unit);
 }
Ejemplo n.º 4
0
 public static Map <A, Map <B, Map <C, Map <D, E> > > > AddOrUpdate <A, B, C, D, E>(this Map <A, Map <B, Map <C, Map <D, E> > > > self, A aKey, B bKey, C cKey, D dKey, E value) =>
 self.AddOrUpdate(
     aKey,
     bKey,
     cKey,
     d => d.AddOrUpdate(dKey, _ => value, value),
     () => Prelude.Map(Tuple(dKey, value))
     );
Ejemplo n.º 5
0
 public static ProcessId AddDispatcher(ProcessName name, Func <ProcessId, IEnumerable <ProcessId> > selector)
 {
     lock (sync)
     {
         dispatchers = dispatchers.AddOrUpdate(name, selector);
     }
     return(ProcessId.Top["disp"][name]);
 }
Ejemplo n.º 6
0
 public static Map <A, Map <B, Map <C, Map <D, E> > > > AddOrUpdate <A, B, C, D, E>(this Map <A, Map <B, Map <C, Map <D, E> > > > self, A aKey, B bKey, C cKey, D dKey, Func <E, E> Some, Func <E> None) =>
 self.AddOrUpdate(
     aKey,
     bKey,
     cKey,
     d => d.AddOrUpdate(dKey, Some, None),
     () => Prelude.Map(Tuple(dKey, None()))
     );
Ejemplo n.º 7
0
        public static Unit AddWatcher(ProcessId watcher, ProcessId watching)
        {
            Process.logInfo(watcher + " is watching " + watching);

            lock (sync)
            {
                watchers = watchers.AddOrUpdate(watching,
                                                Some: set => set.AddOrUpdate(watcher),
                                                None: () => Set(watcher)
                                                );

                watchings = watchings.AddOrUpdate(watcher,
                                                  Some: set => set.AddOrUpdate(watching),
                                                  None: () => Set(watching)
                                                  );
            }
            return(unit);
        }
Ejemplo n.º 8
0
 static void AddLocalRegistered(ProcessName name, ProcessId pid)
 {
     lock (regsync)
     {
         registeredProcessNames = registeredProcessNames.AddOrUpdate(name,
                                                                     Some: set => set.AddOrUpdate(pid),
                                                                     None: () => Set(pid)
                                                                     );
         registeredProcessIds = registeredProcessIds.AddOrUpdate(pid,
                                                                 Some: set => set.AddOrUpdate(name),
                                                                 None: () => Set(name)
                                                                 );
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Provider registration
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="provider">Function that generates a new cluster based on provided config</param>
        /// <returns>Unit</returns>
        public static Unit RegisterProvider(string name, Func <ClusterConfig, ICluster> provider)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (String.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(nameof(name));
            }
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            lock (sync)
            {
                providers = providers.AddOrUpdate(name, provider);
                return(unit);
            }
        }
Ejemplo n.º 10
0
        static MethodInfo DeserialiseFunc(Type type)
        {
            var name   = type.FullName;
            var result = funcs.Find(name);

            if (result.IsSome)
            {
                return(result.LiftUnsafe());
            }

            var func = typeof(JsonConvert).GetTypeInfo()
                       .GetDeclaredMethods("DeserializeObject")
                       .Filter(m => m.IsGenericMethod)
                       .Filter(m => m.GetParameters().Length == 1)
                       .Head()
                       .MakeGenericMethod(type);

            // No locks because we don't really care if it's done
            // more than once, but we do care about locking unnecessarily.
            funcs = funcs.AddOrUpdate(name, func);
            return(func);
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Retrieve a value from the map by key, map it to a new value,
 /// put it back.  If it doesn't exist, add a new one based on None result.
 /// </summary>
 /// <param name="key">Key to find</param>
 /// <exception cref="ArgumentNullException">Throws ArgumentNullException if None is null</exception>
 /// <exception cref="Exception">Throws Exception if Some returns null</exception>
 /// <returns>New map with the mapped value</returns>
 public static Map <K, V> addOrUpdate <K, V>(Map <K, V> map, K key, Func <V, V> Some, V None) =>
 map.AddOrUpdate(key, Some, None);
Ejemplo n.º 12
0
        static Dispatch()
        {
            ProcessName broadcast  = "broadcast";
            ProcessName leastBusy  = "least-busy";
            ProcessName random     = "random";
            ProcessName roundRobin = "round-robin";

            ProcessName first  = "first";
            ProcessName second = "second";
            ProcessName third  = "third";
            ProcessName last   = "last";

            var processes = fun((ProcessId leaf) =>
            {
                if (!leaf.IsValid)
                {
                    return(new ProcessId[0]);
                }
                if (leaf.IsSelection)
                {
                    return(leaf.GetSelection());
                }
                if (leaf.Head().Name == "disp")
                {
                    leaf = leaf.Skip(1);
                    if (!leaf.IsValid)
                    {
                        return(new ProcessId[0]);
                    }
                    return(getFunc(leaf.Head().Name)(leaf.Skip(1)));
                }
                return(new ProcessId[1] {
                    leaf
                });
            });

            // Broadcast
            Broadcast = register(broadcast, processes);

            // First
            First = register(first, leaf => processes(leaf).Take(1));

            // Second
            Second = register(second, leaf => processes(leaf).Skip(1).Take(1));

            // Third
            Third = register(third, leaf => processes(leaf).Skip(2).Take(1));

            // Last
            Last = register(last, leaf => processes(leaf).Reverse().Take(1));

            // Least busy
            LeastBusy = register(leastBusy, leaf =>
                                 processes(leaf)
                                 .Map(pid => Tuple(inboxCount(pid), pid))
                                 .OrderBy(tup => tup.Item1)
                                 .Map(tup => tup.Item2)
                                 .Take(1));

            // Random
            Random = register(random, leaf => {
                var workers = processes(leaf).ToArray();
                return(new ProcessId[1] {
                    workers[Prelude.random(workers.Length)]
                });
            });

            // Round-robin
            object            sync            = new object();
            Map <string, int> roundRobinState = Map.empty <string, int>();

            RoundRobin = register(roundRobin, leaf => {
                var key     = leaf.ToString();
                var workers = processes(leaf).ToArray();
                int index   = 0;
                lock (sync)
                {
                    roundRobinState = roundRobinState.AddOrUpdate(key, x => { index = x % workers.Length; return(x + 1); }, 0);
                }
                return(new ProcessId[1] {
                    workers[index]
                });
            });
        }
Ejemplo n.º 13
0
 public State SetMember(ProcessName nodeName, ClusterNode state) =>
 state == null
         ? RemoveMember(nodeName)
         : new State(Members.AddOrUpdate(nodeName, state), System);
Ejemplo n.º 14
0
 public State SetSession(string sid, Session session) =>
 SetSessions(Sessions.AddOrUpdate(sid, session));
Ejemplo n.º 15
0
 /// <summary>
 /// Atomically adds a new item to the map.
 /// If the key already exists, the new item replaces it.
 /// </summary>
 /// <remarks>Null is not allowed for a Key or a Value</remarks>
 /// <param name="key">Key</param>
 /// <param name="value">Value</param>
 /// <exception cref="ArgumentNullException">Throws ArgumentNullException the key or value are null</exception>
 /// <returns>New Map with the item added</returns>
 public static Map <K, V> addOrUpdate <K, V>(Map <K, V> map, K key, V value) =>
 map.AddOrUpdate(key, value);
Ejemplo n.º 16
0
        /// <summary>
        /// Static ctor
        /// Sets up the default roles
        /// </summary>
        static Role()
        {
            ProcessName first      = "role-first";
            ProcessName second     = "role-second";
            ProcessName third      = "role-third";
            ProcessName last       = "role-last";
            ProcessName next       = "role-next";
            ProcessName prev       = "role-prev";
            ProcessName broadcast  = "role-broadcast";
            ProcessName leastBusy  = "role-least-busy";
            ProcessName random     = "role-random";
            ProcessName roundRobin = "role-round-robin";

            var nextNode = fun((bool fwd) => fun((ProcessId leaf) =>
            {
                var self    = leaf.Take(1).GetName();
                var isNext  = false;
                var nodeMap = Nodes(leaf);

                var nodes = fwd
                    ? nodeMap.Values.Append(nodeMap.Values)
                    : nodeMap.Values.Append(nodeMap.Values).Reverse(); //< TODO: Inefficient

                foreach (var node in nodes)
                {
                    if (isNext)
                    {
                        return(new[] { ProcessId.Top[node.NodeName].Append(leaf.Skip(1)) }.AsEnumerable());
                    }

                    if (node.NodeName == self)
                    {
                        isNext = true;
                    }
                }
                return(new ProcessId[0].AsEnumerable());
            }));

            // Next
            nextRoot = Dispatch.register(next, nextNode(true));

            // Prev
            prevRoot = Dispatch.register(prev, nextNode(false));

            // First
            First = Dispatch.register(first, leaf => NodeIds(leaf).Take(1));

            // Second
            Second = Dispatch.register(second, leaf => NodeIds(leaf).Skip(1).Take(1));

            // Third
            Third = Dispatch.register(third, leaf => NodeIds(leaf).Skip(2).Take(1));

            // Last
            Last = Dispatch.register(last, leaf => NodeIds(leaf).Reverse().Take(1));

            // Broadcast
            Broadcast = Dispatch.register(broadcast, NodeIds);

            // Least busy
            LeastBusy = Dispatch.register(leastBusy, leaf =>
                                          NodeIds(leaf)
                                          .Map(pid => Tuple(inboxCount(pid), pid))
                                          .OrderBy(tup => tup.Item1)
                                          .Map(tup => tup.Item2)
                                          .Take(1));

            // Random
            Random = Dispatch.register(random, leaf => {
                var workers = NodeIds(leaf).ToArray();
                return(new ProcessId[1] {
                    workers[Prelude.random(workers.Length)]
                });
            });

            // Round-robin
            object            sync            = new object();
            Map <string, int> roundRobinState = Map.empty <string, int>();

            RoundRobin = Dispatch.register(roundRobin, leaf => {
                var key     = leaf.ToString();
                var workers = NodeIds(leaf).ToArray();
                int index   = 0;
                lock (sync)
                {
                    roundRobinState = roundRobinState.AddOrUpdate(key, x => { index = x % workers.Length; return(x + 1); }, 0);
                }
                return(new ProcessId[1] {
                    workers[index]
                });
            });
        }
Ejemplo n.º 17
0
 public static Map <A, Map <B, C> > AddOrUpdate <A, B, C>(this Map <A, Map <B, C> > self, A outerKey, B innerKey, Func <C, C> Some, Func <C> None) =>
 self.AddOrUpdate(
     outerKey,
     b => b.AddOrUpdate(innerKey, Some, None),
     () => Prelude.Map(Tuple(innerKey, None()))
     );
Ejemplo n.º 18
0
 public State SetMetadatum(string sid, object metadatum) =>
 SetMetadata(Metadata.AddOrUpdate(sid, metadatum));
Ejemplo n.º 19
0
 public static Map <A, Map <B, C> > AddOrUpdate <A, B, C>(this Map <A, Map <B, C> > self, A outerKey, B innerKey, C value) =>
 self.AddOrUpdate(
     outerKey,
     b => b.AddOrUpdate(innerKey, _ => value, value),
     () => Prelude.Map(Tuple(innerKey, value))
     );
Ejemplo n.º 20
0
 /// <summary>
 /// Adds or updates an item of meta-data
 ///
 /// This is for extending the default strategies behaviours and
 /// allows for state to survive in-between Process errors
 /// </summary>
 public StrategyState SetMetaData <T>(string key, T value) =>
 With(Metadata: Metadata.AddOrUpdate(key, value));
Ejemplo n.º 21
0
 public State SetMember(ProcessName nodeName, ClusterNode state) =>
 new State(Members.AddOrUpdate(nodeName, state));