private ValueTask <IAppConnection> ResolveTargetConnectionAsync( IConsumedMethodReference method, IAppConnection source) { var targetMethods = _registryService.GetMatchingProvidedMethods(source.Info.ApplicationId, method); var targetApps = targetMethods.Select(x => x.ProvidedService.Application.Id).ToList(); return(_appLifecycleManager.GetOrSpawnConnectionAsync(targetApps)); }
private IInvocationStartRequested CreateInvocationTarget(IConsumedMethodReference reference, IClientConnection sourceConnection) { return(_protocolMessageFactory.CreateInvocationStartRequested( reference.ConsumedService.ServiceId, reference.MethodId, reference.ConsumedService.ServiceAlias, sourceConnection.Info.ApplicationId, sourceConnection.Id)); }
public IConsumedMethod GetConsumedMethod(string appId, IConsumedMethodReference reference) { _registryLock.EnterReadLock(); try { var service = GetConsumedService(appId, reference.ConsumedService); return(service.Methods[reference.MethodId]); } finally { _registryLock.ExitReadLock(); } }
public IConsumedMethod GetConsumedMethod(string appId, IConsumedMethodReference reference) { _registryLock.EnterReadLock(); try { var methodId = reference.MethodId; var service = GetConsumedService(appId, reference.ConsumedService); if (service.Methods.TryGetValue(methodId, out var consumedMethod)) { return(consumedMethod); } throw new MetadataViolationException($"Method {methodId} do not exist in service {service.Service.Id} or is not consumed by {appId} application. Available methods: {string.Join(", ", service.Methods.Keys)}"); } finally { _registryLock.ExitReadLock(); } }
public IReadOnlyCollection <IProvidedMethod> GetMatchingProvidedMethods(string appId, IConsumedMethodReference reference) { _registryLock.EnterReadLock(); try { return(GetMatchingProvidedMethods(GetConsumedMethod(appId, reference))); } finally { _registryLock.ExitReadLock(); } }
public T Handle(IConsumedMethodReference target, TArgs args) { return(_consumedMethodHandler(target, args)); }
private async ValueTask <IAppConnection> ResolveTargetConnectionAsync( IConsumedMethodReference method, IAppConnection source, IContextLinkageOptions contextLinkageOptions) { Log.Debug("Resolving target connection for call {{{0}}} from {{{1}}}", method, source); string appId; ResolveMode resolveMode; var targetMethods = _registryService.GetMatchingProvidedMethods(source.Info.ApplicationId, method); var onlineProvidedMethods = _appLifecycleManager .GetOnlineConnections() .Where(x => !x.Id.Equals(source.Id)) .Join( targetMethods.Where(x => GetLaunchMode(x) != LaunchMode.MultiInstance), x => x.Info.ApplicationId, y => y.ProvidedService.Application.Id, (x, y) => (Method: y, AppConnection: x)) .ToArray(); if (_contextLinkageManager.IsContextShouldBeConsidered(contextLinkageOptions, source)) { onlineProvidedMethods = _contextLinkageManager.GetAppsInContexts(contextLinkageOptions, source, true) .Join(onlineProvidedMethods, x => x.ConnectionId.Value, y => y.AppConnection.Id, (x, y) => y).ToArray(); } if (onlineProvidedMethods.Any()) { var connection = onlineProvidedMethods.First().AppConnection; Log.Debug("Resolved target connection for call {{{0}}} from {{{1}}} to online connection: {{{2}}}", method, source, connection); return(connection); } lock (_resolveConnectionSync) { Log.Debug("Resolving target connection for call {{{0}}} from {{{1}}} to offline connection", method, source); var appIds = _appLifecycleManager.FilterCanBeLaunched( targetMethods.Select(x => x.ProvidedService.Application.Id).Distinct()); targetMethods = targetMethods.Join(appIds, x => x.ProvidedService.Application.Id, y => y, (x, y) => x).ToArray(); var singleInstanceMethods = targetMethods.Where(x => GetLaunchMode(x) == LaunchMode.SingleInstance).ToArray(); var onlineConnections = new HashSet <string>(_appLifecycleManager.GetOnlineConnections().Select(connection => connection.Info.ApplicationId)); var candidate = singleInstanceMethods.FirstOrDefault(x => !x.ProvidedService.Application.Id.Equals(source.Info.ApplicationId) && !onlineConnections.Contains(x.ProvidedService.Application.Id)); resolveMode = ResolveMode.SingleInstance; if (candidate == null) { candidate = singleInstanceMethods.FirstOrDefault(x => !onlineConnections.Contains(x.ProvidedService.Application.Id)); resolveMode = ResolveMode.SingleInstance; } if (candidate == null) { candidate = targetMethods.FirstOrDefault(x => GetLaunchMode(x) == LaunchMode.MultiInstance); resolveMode = ResolveMode.MultiInstance; } if (candidate == null) { candidate = targetMethods.FirstOrDefault(x => GetLaunchMode(x) != LaunchMode.None); resolveMode = ResolveMode.MultiInstance; } if (candidate == null) { throw new InvalidOperationException($"Cannot resolve target for invocation {{{method}}} from {{{source}}}"); } Log.Debug("Resolved target connection for call {{{0}}} from {{{1}}} to provided method {{{2}}}", method, source, candidate); appId = candidate.ProvidedService.Application.Id; } var resolvedConnection = await _appLifecycleManager .LaunchAndConnectAsync(appId, resolveMode, source.Info) .ConfigureAwait(false); return(resolvedConnection.AppConnection); }