Exemplo n.º 1
0
        static async Task Main(string[] args)
        {
            var    id                  = System.Guid.NewGuid().ToString();
            var    name                = id;
            var    desc                = "";
            Reg    regs                = new();
            var    catsFilePath        = "categories.json";
            var    tcpPort             = 0;
            var    readRegSRsFromStdIn = false;
            string regFilePath         = "regs.json"; //null;

            for (var i = 0; i < args.Length; i++)
            {
                try
                {
                    if (args[i].StartsWith("id"))
                    {
                        id = args[i].Split('=')[1];
                    }
                    else if (args[i].StartsWith("name"))
                    {
                        name = args[i].Split('=')[1];
                    }
                    else if (args[i].StartsWith("desc"))
                    {
                        desc = args[i].Split('=')[1];
                    }
                    else if (args[i].StartsWith("cats"))
                    {
                        catsFilePath = args[i].Split('=')[1];
                    }
                    else if (args[i].StartsWith("port"))
                    {
                        tcpPort = int.Parse(args[i].Split('=')[1]);
                    }
                    else if (args[i].StartsWith("regstdin"))
                    {
                        readRegSRsFromStdIn = true;
                    }
                    else if (args[i].StartsWith("regfile"))
                    {
                        regFilePath = args[i].Split('=')[1];
                    }
                }
                catch (System.Exception) { }
            }

            if (readRegSRsFromStdIn && Console.IsInputRedirected)
            {
                var regsJson = new System.Text.StringBuilder();
                while (true)
                {
                    var s = Console.ReadLine();
                    if (s == null)
                    {
                        break;
                    }
                    else
                    {
                        regsJson.Append(s);
                    }
                }

                regs = DeserializeRegs(regsJson.ToString());
            }
            else if (regFilePath != null)
            {
                var regsJson = System.IO.File.ReadAllText(regFilePath);
                regs = DeserializeRegs(regsJson.ToString());
            }

            using var conMan = new Common.ConnectionManager();
            var restorer = new Common.Restorer();

            var registry = new ServiceRegistry
            {
                Restorer           = restorer,
                CategoriesFilePath = catsFilePath,
                Id          = id,
                Name        = name,
                Description = desc
            };

            conMan.Bind(IPAddress.Any, tcpPort, restorer);
            restorer.TcpPort = conMan.Port;

            Console.WriteLine("Started ServiceRegistry with these Categories:");
            foreach (var cat in registry.Categories)
            {
                Console.WriteLine(cat.Id);
            }
            var registrySturdyRef = restorer.Save(BareProxy.FromImpl(registry)).SturdyRef;

            Console.WriteLine($"registry_sr: {registrySturdyRef}");
            await TryRegisterService(conMan, regs.registry, registry);

            var registrar    = new ServiceRegistry.Registrar(registry, restorer);
            var regSturdyRef = restorer.Save(BareProxy.FromImpl(registrar)).SturdyRef;

            Console.WriteLine($"registrar_sr: {regSturdyRef}");
            //await TryRegisterService(conMan, regs.registrar, registrar);

            var registryAdmin          = new ServiceRegistry.Admin(registry);
            var registryAdminSturdyRef = restorer.Save(BareProxy.FromImpl(registryAdmin)).SturdyRef;

            Console.WriteLine($"registry_admin_sr: {registryAdminSturdyRef}");
            //await TryRegisterService(conMan, regs.registry_admin, registryAdmin);

            var serviceAdmin = new Service.Admin(registry, (info) => {
                registry.Id          = info.Id;
                registry.Name        = info.Name;
                registry.Description = info.Description;
            });
            var serviceAdminSturdyRef = restorer.Save(BareProxy.FromImpl(serviceAdmin)).SturdyRef;

            Console.WriteLine($"service_admin_sr: {serviceAdminSturdyRef}");
            //await TryRegisterService(conMan, regs.service_admin, serviceAdmin);

            while (true)
            {
                System.Threading.Thread.Sleep(1000);
            }

            //Console.WriteLine("Press RETURN to stop listening");
            //Console.ReadLine();
        }
            // register @0 (cap :Common.Identifiable, regName :Text, categoryId :Text) -> (unreg :Common.Action, reregSR :Text);
            public Task <(Mas.Rpc.Common.IAction, string)> Register(Rpc.Common.IIdentifiable cap, string regName, string categoryId, CancellationToken cancellationToken_ = default)
            {
                if (categoryId == null || regName == null)
                {
                    return(Task.FromResult <(Mas.Rpc.Common.IAction, string)>((null, null)));
                }

                if (_registry._CatId2SupportedCategories.ContainsKey(categoryId))
                {
                    try
                    {
                        // uuid to register cap under
                        var regId = System.Guid.NewGuid().ToString();

                        // attach a membrane around the capability to intercept save messages
                        var interceptedCap = _registry._savePolicy.Attach(cap);

                        // create an unregister action
                        var unreg = new Common.Action(() => {
                            _registry._regId2Entry.TryRemove(regId, out var removedRegData);
                            removedRegData.ReregUnsave?.Do();
                        }, restorer: _restorer, callActionOnDispose: true);

                        var regData = new RegData
                        {
                            Entry = new Registry.Entry()
                            {
                                CategoryId = categoryId,
                                Ref        = interceptedCap,
                                Name       = regName,
                            },
                            Unreg = unreg,
                            Cap   = Proxy.Share(cap)
                        };

                        // create an reregister action and sturdy ref to it
                        var rereg = new Common.Action1((object anyp) => {
                            if (anyp is Rpc.Common.IIdentifiable cap)
                            {
                                var interceptedCap = _registry._savePolicy.Attach(cap);

                                _registry._regId2Entry[regId] = new RegData
                                {
                                    Entry = new Registry.Entry()
                                    {
                                        CategoryId = categoryId,
                                        Ref        = interceptedCap,
                                        Name       = regName,
                                    },
                                    Unreg = unreg,
                                    Cap   = Proxy.Share(cap)
                                };
                            }
                        });
                        // get the sturdy ref to the reregister action
                        var res = _restorer.Save(BareProxy.FromImpl(rereg));
                        // and save the unsave action to remove the sturdy ref on unregistration of the capability
                        regData.ReregUnsave = res.UnsaveAction;

                        _registry._regId2Entry[regId] = regData;

                        // !!! note it is fine to accept manually aquired sturdy refs to the unreg action
                        // !!! to not be automatically removed on unregistration of the capability as the user might
                        // !!! still want to keep the aquired sturdy ref to get a reference to the capability
                        // !!! in this case the registry's vat acts just as proxy and not anymore as registry

                        return(Task.FromResult <(Mas.Rpc.Common.IAction, string)>((unreg, res.SturdyRef)));
                    }
                    catch (Capnp.Rpc.RpcException e)
                    {
                        Console.Error.WriteLine(e.Message);
                    }
                }
                return(Task.FromResult <(Mas.Rpc.Common.IAction, string)>((null, null)));
            }