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))); }