public ILogicalEndPoint <TAddress> CreateLogicalEndPoint(EndPointAddress endPoint) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (_isDisposed != 0) // Volatile read op. { throw new ObjectDisposedException(GetType().FullName); } // We have to ensure that only a single logical end-point exists for each address at any given time. lock (_endPointsLock) { if (_endPoints == null) { throw new ObjectDisposedException(GetType().FullName); } if (_endPoints.TryGetValue(endPoint, out _)) { throw new Exception("End point already present!"); // TODO } var logicalEndPoint = CreateLogicalEndPointInternal(endPoint); _endPoints.Add(endPoint, logicalEndPoint); return(logicalEndPoint); } }
private IPhysicalEndPoint <TAddress> GetMultiplexPhysicalEndPoint(EndPointAddress endPoint) { var result = _endPointMultiplexer.GetPhysicalEndPoint("end-points/" + endPoint.ToString()); // TODO: This should be configurable Assert(result != null); return(result); }
private LogicalEndPoint CreateLogicalEndPointInternal(EndPointAddress endPoint) { var physicalEndPoint = GetMultiplexPhysicalEndPoint(endPoint); var logger = _loggerFactory?.CreateLogger <LogicalEndPoint>(); return(new LogicalEndPoint(this, physicalEndPoint, endPoint, logger)); }
private async ValueTask <IDispatchResult> InternalDispatchAsync( DispatchDataDictionary dispatchData, bool publish, EndPointAddress endPoint, CancellationToken cancellation) { if (endPoint == await GetLocalEndPointAsync(cancellation)) { var(result, _) = await TryDispatchLocalAsync(dispatchData, publish, allowRouteDescend : true, localDispatch : true, cancellation); return(result); } else { var route = new Route(_typeConversion.SerializeType(dispatchData.MessageType)); var serializedMessage = new Message(); SerializeDispatchData(serializedMessage, dispatchData); var serializedResult = await _messageRouter.RouteAsync(route, serializedMessage, publish, endPoint, cancellation); var result = DeserializeDispatchResult(serializedResult); return(result); } }
public async Task UnmapEndPointAsync(EndPointAddress endPoint, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } var path = GetPath(endPoint); await _coordinationManager.DeleteAsync(path, recursive : true, cancellation : cancellation); }
public async Task RemoveRoutesAsync(EndPointAddress endPoint, bool removePersistentRoutes, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } var session = (await _coordinationManager.GetSessionAsync(cancellation)).ToString(); var path = GetReversePath(session, endPoint); var reverseEntry = await _coordinationManager.GetAsync(path, cancellation); if (reverseEntry == null) { return; } var tasks = new List <Task>(capacity: reverseEntry.Children.Count); foreach (var reverseRouteEntry in await reverseEntry.GetChildrenEntriesAsync(cancellation)) { var route = new Route(reverseRouteEntry.Name.Segment.ConvertToString()); var routePath = GetPath(route, endPoint, session); if (!removePersistentRoutes) { using (var stream = reverseRouteEntry.OpenStream()) using (var reader = new BinaryReader(stream)) { var registrationOptions = (RouteRegistrationOptions)reader.ReadInt32(); if (!registrationOptions.IncludesFlag(RouteRegistrationOptions.Transient)) { continue; } var reverseRouteEntryDeletion = _coordinationManager.DeleteAsync(reverseRouteEntry.Path, recursive: true, cancellation: cancellation); tasks.Add(reverseRouteEntryDeletion.AsTask()); } } var routeEntryDeletion = _coordinationManager.DeleteAsync(routePath, cancellation: cancellation); tasks.Add(routeEntryDeletion.AsTask()); } await Task.WhenAll(tasks); if (removePersistentRoutes) { await _coordinationManager.DeleteAsync(path, recursive : true, cancellation : cancellation); } }
public async Task RemoveRouteAsync(EndPointAddress endPoint, Route route, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } var session = (await _coordinationManager.GetSessionAsync(cancellation)).ToString(); var path = GetPath(route, endPoint, session); await _coordinationManager.DeleteAsync(path, cancellation : cancellation); var reversePath = GetReversePath(session, endPoint, route); await _coordinationManager.DeleteAsync(reversePath, cancellation : cancellation); }
public async ValueTask <IEnumerable <TAddress> > GetMapsAsync(EndPointAddress endPoint, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } var endPointEntry = await GetLogicalAddressEntryAsync(endPoint, cancellation); Assert(endPointEntry != null); var entries = await endPointEntry.GetChildrenEntries().ToArray(cancellation); return(entries.Select(p => _addressConversion.DeserializeAddress(p.Value.ToArray()))); }
public RouteTarget(EndPointAddress endPoint, RouteRegistrationOptions registrationOptions) { if (endPoint == default) { this = default; return; } if (!registrationOptions.IsValid()) { throw new ArgumentException("Invalid enum valid.", nameof(registrationOptions)); } EndPoint = endPoint; RegistrationOptions = registrationOptions; }
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); } }
public ValueTask <IDispatchResult> DispatchAsync( DispatchDataDictionary dispatchData, bool publish, EndPointAddress endPoint, CancellationToken cancellation = default) { if (dispatchData == null) { throw new ArgumentNullException(nameof(dispatchData)); } if (endPoint != default) { return(InternalDispatchAsync(dispatchData, publish, endPoint, cancellation)); } return(InternalDispatchAsync(dispatchData, publish, cancellation)); }
public IMessageRouter CreateMessageRouter(EndPointAddress endPoint, ISerializedMessageHandler serializedMessageHandler) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (serializedMessageHandler == null) { throw new ArgumentNullException(nameof(serializedMessageHandler)); } if (_logicalEndPoint.EndPoint == endPoint) { return(CreateMessageRouterInternal(_logicalEndPoint, serializedMessageHandler)); } var logicalEndPoint = _endPointManager.CreateLogicalEndPoint(endPoint); return(CreateMessageRouterInternal(logicalEndPoint, serializedMessageHandler)); }
public async Task MapEndPointAsync(EndPointAddress endPoint, TAddress address, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (address == null) { throw new ArgumentNullException(nameof(address)); } if (address.Equals(default(TAddress))) { throw new ArgumentDefaultException(nameof(address)); } var session = (await _coordinationManager.GetSessionAsync(cancellation)).ToString(); var path = GetPath(endPoint, session); await _coordinationManager.GetOrCreateAsync(path, _addressConversion.SerializeAddress(address), EntryCreationModes.Ephemeral, cancellation); }
public ILogicalEndPoint <TAddress> GetLogicalEndPoint(EndPointAddress endPoint) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } lock (_endPointsLock) { if (_endPoints == null) { throw new ObjectDisposedException(GetType().FullName); } if (_endPoints.TryGetValue(endPoint, out var logicalEndPoint)) { return(logicalEndPoint); } return(null); } }
public static void Write(this BinaryWriter writer, EndPointAddress endPointAddress) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (endPointAddress == default) { writer.Write(0); } var utf8EncodedValue = endPointAddress.Utf8EncodedValue; writer.Write(utf8EncodedValue.Length); writer.Flush(); if (utf8EncodedValue.Length > 0) { var stream = writer.BaseStream; stream.Write(utf8EncodedValue.Span); } }
public async Task UnmapEndPointAsync(EndPointAddress endPoint, TAddress address, CancellationToken cancellation) { if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } if (address == null) { throw new ArgumentNullException(nameof(address)); } if (address.Equals(default(TAddress))) { throw new ArgumentDefaultException(nameof(address)); } var endPointEntry = await GetLogicalAddressEntryAsync(endPoint, cancellation); var session = (await _coordinationManager.GetSessionAsync(cancellation)).ToString(); var path = GetPath(endPoint, session); await _coordinationManager.DeleteAsync(path, cancellation : cancellation); }
public void Deconstruct(out EndPointAddress endPoint, out RouteRegistrationOptions registrationOptions) { endPoint = EndPoint; registrationOptions = RegistrationOptions; }
public static async Task HandleAsync( this ILogicalEndPointReceiveResult messageReceiveResult, Func <IMessage, EndPointAddress, CancellationToken, Task <(IMessage response, bool handled)> > handler,
ILogicalEndPoint IEndPointManager.GetLogicalEndPoint(EndPointAddress endPoint) { return(GetLogicalEndPoint(endPoint)); }
private async ValueTask <(IMessage response, bool handled)> InternalRouteAsync(Route route, IMessage serializedMessage, bool publish, EndPointAddress endPoint, CancellationToken cancellation) { Assert(endPoint != default); var localEndPoint = await GetLocalEndPointAsync(cancellation); // This does short-circuit the dispatch to the remote end-point. // Any possible replicates do not get any chance to receive the message. // => Requests are kept local to the machine. if (endPoint == localEndPoint) { _logger?.LogDebug($"Message router for end-point '{localEndPoint}': Dispatching request message locally."); return(await RouteToLocalAsync(route, serializedMessage, publish, localDispatch : true, cancellation)); } _logger?.LogDebug($"Message router for end-point '{localEndPoint}': Dispatching request message to remote end point '{endPoint}'."); // Remove all frames from other protocol stacks. serializedMessage.Trim(); // TODO // We do not want to override frames. Assert(serializedMessage.FrameIndex == serializedMessage.FrameCount - 1); EncodeMessage(serializedMessage, publish, localDispatch: false, route); var(response, handled) = await _logicalEndPoint.SendAsync(serializedMessage, endPoint, cancellation); _logger?.LogDebug($"Message router for end-point '{localEndPoint}': Processing response message."); // TODO response.Trim(); // TODO return(response, handled); }
public async ValueTask <IMessage> RouteAsync(Route route, IMessage serializedMessage, bool publish, EndPointAddress endPoint, CancellationToken cancellation) { if (route == null) { throw new ArgumentNullException(nameof(route)); } if (serializedMessage == null) { throw new ArgumentNullException(nameof(serializedMessage)); } if (endPoint == default) { throw new ArgumentDefaultException(nameof(endPoint)); } try { using (var guard = await _disposeHelper.GuardDisposalAsync(cancellation)) { var(response, _) = await InternalRouteAsync(route, serializedMessage, publish, endPoint, cancellation); return(response); } } catch (OperationCanceledException) when(_disposeHelper.IsDisposed) { throw new ObjectDisposedException(GetType().FullName); } }
private async Task <(IMessage response, bool handled)> HandleAsync(IMessage message, EndPointAddress remoteEndPoint, CancellationToken cancellation) { var localEndPoint = await GetLocalEndPointAsync(cancellation); var(publish, localDispatch, route) = DecodeMessage(message); _logger?.LogDebug($"End-point '{localEndPoint}': Processing request message."); return(await RouteToLocalAsync(route, message, publish, localDispatch, cancellation)); }
ILogicalEndPoint IEndPointManager.CreateLogicalEndPoint(EndPointAddress endPoint) { return(CreateLogicalEndPoint(endPoint)); }
private ValueTask <IEntry> GetLogicalAddressEntryAsync(EndPointAddress endPoint, CancellationToken cancellation) { var path = GetPath(endPoint); return(_coordinationManager.GetOrCreateAsync(path, ReadOnlyMemory <byte> .Empty, EntryCreationModes.Default, cancellation)); }
private static CoordinationEntryPath GetPath(EndPointAddress endPoint, string session) { return(_mapsRootPath.GetChildPath(endPoint.ToString(), session)); }
private static CoordinationEntryPath GetReversePath(string session, EndPointAddress endPoint, Route route) { return(_reverseRoutesRootPath.GetChildPath(session, endPoint.ToString(), route.ToString())); }
private static CoordinationEntryPath GetPath(Route route, EndPointAddress endPoint, string session) { var uniqueEntryName = IdGenerator.GenerateId(endPoint.ToString(), session); return(_routesRootPath.GetChildPath(route.ToString(), uniqueEntryName)); }
public RemoteMessagingOptions() { LocalEndPoint = new EndPointAddress(Assembly.GetEntryAssembly().GetName().Name); }