Beispiel #1
0
        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));
        }
Beispiel #2
0
 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);
        }