private async Task <(EndPointAddress endPoint, string securityToken)> AddClientCoreAsync(CancellationToken cancellation) { var now = _dateTimeProvider.GetCurrentTime(); var securityToken = Guid.NewGuid().ToString(); var leaseEnd = now + Timeout; var securityTokenBytesCount = Encoding.UTF8.GetByteCount(securityToken); using (ArrayPool <byte> .Shared.Rent(8 + 4 + securityTokenBytesCount, out var bytes)) { var payloadLength = EncodePayload(bytes, securityToken.AsSpan(), leaseEnd); var payload = bytes.AsMemory().Slice(start: 0, payloadLength); EndPointAddress endPoint; do { endPoint = AllocateEndPointAddress(); var path = GetPath(endPoint); try { await _coordinationManager.CreateAsync(path, payload, cancellation : cancellation); _logger?.LogDebug($"Assigning end-point '{endPoint.ToString()}' to recently connected client."); break; } catch (DuplicateEntryException) // TODO: Add a TryCreateAsync method to the coordination service. { continue; } }while (cancellation.ThrowOrContinue()); return(endPoint, securityToken); } }
public async Task AddRouteAsync(EndPointAddress endPoint, RouteRegistration routeRegistration, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (routeRegistration == default) { throw new ArgumentDefaultException(nameof(routeRegistration)); } var session = (await _coordinationManager.GetSessionAsync(cancellation)).ToString(); var entryCreationMode = EntryCreationModes.Default; if (routeRegistration.RegistrationOptions.IncludesFlag(RouteRegistrationOptions.Transient)) { entryCreationMode |= EntryCreationModes.Ephemeral; } var reversePath = GetReversePath(session, endPoint, routeRegistration.Route); using (var stream = new MemoryStream(capacity: 4)) { using (var writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true)) { writer.Write((int)routeRegistration.RegistrationOptions); } var payload = stream.ToArray(); await _coordinationManager.CreateAsync(reversePath, payload, entryCreationMode, cancellation); } var path = GetPath(routeRegistration.Route, endPoint, session); using (var stream = new MemoryStream(capacity: 4 + 4 + endPoint.Utf8EncodedValue.Length)) { using (var writer = new BinaryWriter(stream, Encoding.UTF8, leaveOpen: true)) { writer.Write((int)routeRegistration.RegistrationOptions); writer.Write(endPoint); } var payload = stream.ToArray(); // TODO: What to do if the entry already existed but with different options? await _coordinationManager.GetOrCreateAsync(path, payload, entryCreationMode, cancellation); } }