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)); }
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); } }
public ModuleDependency(ModuleIdentifier module, ModuleVersionRange versionRange) { if (module == ModuleIdentifier.UnknownModule) { this = Unknown; } else { Module = module; VersionRange = versionRange; } }
public ModuleReleaseIdentifier(ModuleIdentifier module, ModuleVersion version) { if (module == ModuleIdentifier.UnknownModule || version == ModuleVersion.Unknown) { this = UnknownModuleRelease; } else { Module = module; Version = version; } }
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; }
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()); }
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. }
public void Deconstruct(out ModuleIdentifier module, out ModuleVersionRange versionRange) { module = Module; versionRange = VersionRange; }
public ModuleVersionRange this[ModuleIdentifier key] { get => _dependencies[key];
private static CoordinationEntryPath GetRunningModulePath(ModuleIdentifier module, Session session) { return(_rootRunningPath.GetChildPath(module.Name, session.ToString())); }
private static CoordinationEntryPath GetRunningModulePath(ModuleIdentifier module) { return(_rootRunningPath.GetChildPath(module.Name)); }
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()); }