Esempio n. 1
0
        public IMethodStateStorage GetStorage(ServiceId serviceId, MethodId methodId, bool returnNullIfNotFound = false)
        {
            if (_persistenceMethods.Count == 0)
            {
                if (returnNullIfNotFound)
                {
                    return(null);
                }
                else
                {
                    throw new MethodStateStorageNotFoundException("There are no method state storages registered.");
                }
            }

            var serviceRef = _serviceResolver.Resolve(serviceId);
            var methodRef  = _methodResolver.Resolve(serviceRef.Definition, methodId);

            lock (_storageMap)
            {
                if (_storageMap.TryGetValue(methodRef.Definition, out var cachedStorage))
                {
                    return(cachedStorage);
                }
            }

            var serviceCategory = serviceRef.Definition.Type == ServiceType.External ? "_external" : "_local";
            var methodCategory  = methodRef.Definition.IsQuery ? "queries" : "commands";

            var persistenceType = _communicationSettingsProvider.GetMethodSettings(methodRef.Definition).PersistenceType;

            IPersistenceMethod persistenceMethod;

            if (string.IsNullOrWhiteSpace(persistenceType))
            {
                if (_persistenceMethods.Count == 1)
                {
                    persistenceMethod = _persistenceMethods.First().Value;
                }
                else
                {
                    if (returnNullIfNotFound)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new MethodStateStorageNotFoundException("Multiple method state storages are available.");
                    }
                }
            }
            else
            {
                if (!_persistenceMethods.TryGetValue(persistenceType, out persistenceMethod))
                {
                    if (returnNullIfNotFound)
                    {
                        return(null);
                    }
                    else
                    {
                        throw new MethodStateStorageNotFoundException($"Method state storage '{persistenceType}' is not registered.");
                    }
                }
            }

            var servicesSection = _configuration.GetSection("services");
            var serviceSection  = servicesSection.GetSection(serviceRef.Definition.Name);

            var storageConfig = GetConfiguraion(
                _configuration.GetSection("persistence"),
                _configuration.GetSection(methodCategory).GetSection("persistence"),
                servicesSection.GetSection(serviceCategory).GetSection("persistence"),
                servicesSection.GetSection(serviceCategory).GetSection(methodCategory).GetSection("persistence"),
                serviceSection.GetSection("persistence"),
                serviceSection.GetSection(methodCategory).GetSection("_all").GetSection("persistence"),
                serviceSection.GetSection(methodCategory).GetSection(methodRef.Definition.Name).GetSection("persistence"));

            var storage = persistenceMethod.CreateMethodStateStorage(storageConfig);

            lock (_storageMap)
            {
                if (_storageMap.TryGetValue(methodRef.Definition, out var cachedStorage))
                {
                    (storage as IDisposable)?.Dispose();
                    return(cachedStorage);
                }

                _storageMap.Add(methodRef.Definition, storage);
                return(storage);
            }
        }
Esempio n. 2
0
        public Task Execute <TParameters>(IProxy proxy, MethodInfo methodInfo, ref TParameters parameters)
            where TParameters : IValueContainer
        {
            var serviceProxyContext = (ServiceProxyContext)proxy.Context;
            var methodDefinition    = serviceProxyContext.Definition.FindMethod(methodInfo);

            if (methodDefinition == null || methodDefinition.IsIgnored)
            {
                var invoker = _methodInvokerFactory.Create(methodInfo);
                return(invoker.Invoke(proxy, parameters));
            }

            var intent = new ExecuteRoutineIntent
            {
                Id         = _idGenerator.NewId(),
                Service    = serviceProxyContext.Descriptor.Id,
                Method     = _routineMethodIdProvider.GetId(methodInfo),
                Parameters = parameters
            };

            Type taskResultType =
                methodInfo.ReturnType == typeof(void)
                ? TaskAccessor.VoidTaskResultType
                : TaskAccessor.GetTaskResultType(methodInfo.ReturnType);

            var taskState = new RoutineReference
            {
                ServiceId = intent.Service,
                MethodId  = intent.Method,
                IntentId  = intent.Id
#warning must have id of actual routine for dynamic subscription (subscribe after a routine already scheduled).
            };

            var proxyTask = TaskAccessor.CreateTask(taskState, taskResultType);

            bool invokedByRunningMethod = _transitionScope.IsActive &&
                                          IsCalledByRoutine(
                _transitionScope.CurrentMonitor.Context,
                // Skip 2 stack frames: current method and dynamically-generated proxy.
                // WARNING! DO NOT PUT 'new StackFrame()' into a helper method!
                new StackFrame(skipFrames: 2, fNeedFileInfo: false));

            bool ignoreTransaction = !invokedByRunningMethod;

            if (!ignoreTransaction && _transitionScope.IsActive)
            {
                var runningMethodSettings = _communicationSettingsProvider.GetMethodSettings(
                    _transitionScope.CurrentMonitor.Context.MethodRef.Definition);

                if (!runningMethodSettings.Transactional)
                {
                    ignoreTransaction = true;
                }
            }

            if (!ignoreTransaction)
            {
                var methodSettings = _communicationSettingsProvider.GetMethodSettings(methodDefinition);
                if (methodSettings.IgnoreTransaction)
                {
                    ignoreTransaction = true;
                }
            }

            if (ignoreTransaction)
            {
                ExecuteAndAwaitInBackground(intent, proxyTask);
            }
            else
            {
                _transitionScope.CurrentMonitor.RegisterIntent(intent, proxyTask);
            }

            return(proxyTask);
        }