Example #1
0
        private async Task WriteRunningModuleEntryAsync(
            ModuleIdentifier module,
            EndPointAddress endPoint,
            ICollection <ReadOnlyMemory <char> > prefixes,
            Session session,
            CancellationToken cancellation)
        {
            var path = GetRunningModulePath(module, session);

            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    writer.Write(endPoint);
                    writer.Write(prefixes.Count());

                    foreach (var prefix in prefixes)
                    {
                        WritePrefix(writer, prefix);
                    }
                }

                var payload = stream.ToArray();
                await _coordinationManager.GetOrCreateAsync(path, payload, EntryCreationModes.Ephemeral, cancellation);
            }
        }
        private async ValueTask <IModuleMetadata> GetMetadataCoreAsync(Assembly entryAssembly, string metadataPath, CancellationToken cancellation)
        {
            if (File.Exists(metadataPath))
            {
                try
                {
                    using (var stream = new FileStream(metadataPath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true))
                    {
                        return(await _metadataReader.ReadMetadataAsync(stream, cancellation));
                    }
                }
                catch (FileNotFoundException) { }
                catch (DirectoryNotFoundException) { }
            }

            // If we reach this point, we cannot find a manifest resource/file.
            // We now assembly our own metadata
            var asmName    = entryAssembly.GetName();
            var asmVersion = asmName.Version;

            var module  = new ModuleIdentifier(asmName.Name);
            var version = new ModuleVersion(asmVersion.Major, asmVersion.Minor, asmVersion.Revision, isPreRelease: false);

            return(new ModuleMetadata(module, version));
        }
Example #3
0
        public async Task RemoveModuleAsync(ModuleIdentifier module, CancellationToken cancellation)
        {
            if (module == default)
            {
                throw new ArgumentDefaultException(nameof(module));
            }

            var session = await _coordinationManager.GetSessionAsync(cancellation);

            var runningModulePath = GetRunningModulePath(module, session);

            var entry = await _coordinationManager.GetAsync(runningModulePath, cancellation);

            if (entry == null)
            {
                return;
            }

            await _coordinationManager.DeleteAsync(runningModulePath, cancellation : cancellation);

            var(endPoint, prefixes) = ReadRunningModuleEntry(entry);

            foreach (var prefix in prefixes)
            {
                var prefixPath = GetPrefixPath(prefix, endPoint, session, normalize: false);
                await _coordinationManager.DeleteAsync(prefixPath, cancellation : cancellation);
            }
        }
Example #4
0
 public ModuleDependency(ModuleIdentifier module, ModuleVersionRange versionRange)
 {
     if (module == ModuleIdentifier.UnknownModule)
     {
         this = Unknown;
     }
     else
     {
         Module       = module;
         VersionRange = versionRange;
     }
 }
Example #5
0
 public ModuleReleaseIdentifier(ModuleIdentifier module, ModuleVersion version)
 {
     if (module == ModuleIdentifier.UnknownModule || version == ModuleVersion.Unknown)
     {
         this = UnknownModuleRelease;
     }
     else
     {
         Module  = module;
         Version = version;
     }
 }
Example #6
0
        public ModuleMetadata(ModuleIdentifier module, ModuleVersion version)
        {
            if (module == default)
            {
                throw new ArgumentDefaultException(nameof(module));
            }

            if (version == default)
            {
                throw new ArgumentDefaultException(nameof(version));
            }

            _version = version;
            _module  = module;
        }
Example #7
0
        public async ValueTask <IEnumerable <EndPointAddress> > GetEndPointsAsync(ModuleIdentifier module, CancellationToken cancellation)
        {
            if (module == default)
            {
                throw new ArgumentDefaultException(nameof(module));
            }

            var runningModulePath = GetRunningModulePath(module);

            var entry = await _coordinationManager.GetAsync(runningModulePath, cancellation);

            if (entry == null)
            {
                return(Enumerable.Empty <EndPointAddress>());
            }

            return(await entry.GetChildrenEntries().Select(p => ReadRunningModuleEntry(p).endPoint).Distinct().ToList());
        }
Example #8
0
        public async Task AddModuleAsync(ModuleIdentifier module, EndPointAddress endPoint, IEnumerable <ReadOnlyMemory <char> > prefixes, CancellationToken cancellation)
        {
            if (module == default)
            {
                throw new ArgumentDefaultException(nameof(module));
            }

            if (endPoint == default)
            {
                throw new ArgumentDefaultException(nameof(endPoint));
            }

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

            if (!prefixes.Any())
            {
                throw new ArgumentException("The collection must not be empty.", nameof(prefixes));
            }

            if (prefixes.Any(prefix => prefix.Span.IsEmptyOrWhiteSpace()))
            {
                throw new ArgumentException("The collection must not contain null entries or entries that are empty or contain whitespace only.", nameof(prefixes));
            }

            var prefixCollection = (prefixes as ICollection <ReadOnlyMemory <char> >) ?? prefixes.ToList();
            var session          = await _coordinationManager.GetSessionAsync(cancellation);

            var tasks = new List <Task>(capacity: prefixCollection.Count());

            foreach (var prefix in prefixCollection)
            {
                tasks.Add(WriteModulePrefixEntryAsync(prefix, endPoint, session, cancellation));
            }

            await Task.WhenAll(tasks);

            await WriteRunningModuleEntryAsync(module, endPoint, prefixCollection, session, cancellation);

            // TODO: When cancelled, alls completed operations should be reverted.
            // TODO: The RemoveModuleAsync alogrithm assumes that there are no prefix entries, if the running module entry is not present. We should reflect this assumtion here.
        }
Example #9
0
 public void Deconstruct(out ModuleIdentifier module, out ModuleVersionRange versionRange)
 {
     module       = Module;
     versionRange = VersionRange;
 }
Example #10
0
 public ModuleVersionRange this[ModuleIdentifier key]
 {
     get => _dependencies[key];
Example #11
0
 private static CoordinationEntryPath GetRunningModulePath(ModuleIdentifier module, Session session)
 {
     return(_rootRunningPath.GetChildPath(module.Name, session.ToString()));
 }
Example #12
0
 private static CoordinationEntryPath GetRunningModulePath(ModuleIdentifier module)
 {
     return(_rootRunningPath.GetChildPath(module.Name));
 }
Example #13
0
        public async ValueTask <IEnumerable <ReadOnlyMemory <char> > > GetPrefixesAsync(ModuleIdentifier module, CancellationToken cancellation)
        {
            if (module == default)
            {
                throw new ArgumentDefaultException(nameof(module));
            }

            var runningModulePath = GetRunningModulePath(module);

            var entry = await _coordinationManager.GetAsync(runningModulePath, cancellation);

            if (entry == null)
            {
                return(Enumerable.Empty <ReadOnlyMemory <char> >());
            }

            return(await entry.GetChildrenEntries().SelectMany(p => ReadRunningModuleEntry(p).prefixes.ToAsyncEnumerable()).Distinct().ToList());
        }