Esempio n. 1
0
        private async Task CallAsyncCore(MethodInfo method, IDictionary <string, object> arguments,
                                         CancellationToken cancellationToken)
        {
            await EnsureHostStartedAsync(cancellationToken);

            IFunctionDefinition function = ResolveFunctionDefinition(method, _context.FunctionLookup);
            IFunctionInstance   instance = CreateFunctionInstance(function, arguments);

            IDelayedException exception = await _context.Executor.TryExecuteAsync(instance, cancellationToken);

            if (exception != null)
            {
                exception.Throw();
            }
        }
Esempio n. 2
0
        private async Task CallAsyncCore(IFunctionDefinition function, object functionKey, IDictionary <string, object> arguments, CancellationToken cancellationToken)
        {
            Validate(function, functionKey);

            IFunctionInstance instance = CreateFunctionInstance(function, arguments);

            IDelayedException exception = null;

            exception = await _context.Executor.TryExecuteAsync(instance, cancellationToken);

            if (exception != null)
            {
                exception.Throw();
            }
        }
Esempio n. 3
0
        /// <summary>Calls a job method.</summary>
        /// <param name="name">The name of the function to call.</param>
        /// <param name="arguments">The argument names and values to bind to parameters in the job method. In addition to parameter values, these may also include binding data values. </param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task"/> that will call the job method.</returns>
        public async Task CallAsync(string name, IDictionary <string, object> arguments = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            ThrowIfDisposed();

            await EnsureHostInitializedAsync(cancellationToken);

            IFunctionDefinition function = _context.FunctionLookup.LookupByName(name);

            Validate(function, name);
            IFunctionInstance instance = CreateFunctionInstance(function, arguments);

            IDelayedException exception = await _context.Executor.TryExecuteAsync(instance, cancellationToken);

            if (exception != null)
            {
                exception.Throw();
            }
        }
Esempio n. 4
0
        internal static async Task ExecuteWithWatchersAsync(IFunctionInstance instance,
                                                            IReadOnlyDictionary <string, IValueProvider> parameters,
                                                            TraceWriter traceWriter,
                                                            CancellationTokenSource functionCancellationTokenSource)
        {
            IFunctionInvoker       invoker        = instance.Invoker;
            IReadOnlyList <string> parameterNames = invoker.ParameterNames;

            Tuple <object[], IDelayedException> preparedParameters = await PrepareParametersAsync(parameterNames, parameters);

            object[]          invokeParameters        = preparedParameters.Item1;
            IDelayedException delayedBindingException = preparedParameters.Item2;

            if (delayedBindingException != null)
            {
                // This is done inside a watcher context so that each binding error is publish next to the binding in
                // the parameter status log.
                delayedBindingException.Throw();
            }

            // if the function is a Singleton, aquire the lock
            SingletonLock singleton = await GetSingletonLockAsync(parameters);

            if (singleton != null)
            {
                await singleton.AcquireAsync(functionCancellationTokenSource.Token);
            }

            // Create a source specifically for timeouts
            using (CancellationTokenSource timeoutTokenSource = new CancellationTokenSource())
            {
                MethodInfo       method           = instance.FunctionDescriptor.Method;
                TimeoutAttribute timeoutAttribute = TypeUtility.GetHierarchicalAttributeOrNull <TimeoutAttribute>(method);
                bool             throwOnTimeout   = timeoutAttribute == null ? false : timeoutAttribute.ThrowOnTimeout;
                var      timer         = StartFunctionTimeout(instance, timeoutAttribute, timeoutTokenSource, traceWriter);
                TimeSpan timerInterval = timer == null ? TimeSpan.MinValue : TimeSpan.FromMilliseconds(timer.Interval);
                try
                {
                    await InvokeAsync(invoker, invokeParameters, timeoutTokenSource, functionCancellationTokenSource,
                                      throwOnTimeout, timerInterval, instance);
                }
                finally
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer.Dispose();
                    }
                }
            }

            // Process any out parameters and persist any pending values.
            // Ensure IValueBinder.SetValue is called in BindStepOrder. This ordering is particularly important for
            // ensuring queue outputs occur last. That way, all other function side-effects are guaranteed to have
            // occurred by the time messages are enqueued.
            string[] parameterNamesInBindOrder = SortParameterNamesInStepOrder(parameters);
            foreach (string name in parameterNamesInBindOrder)
            {
                IValueProvider provider = parameters[name];
                IValueBinder   binder   = provider as IValueBinder;

                if (binder != null)
                {
                    object argument = invokeParameters[GetParameterIndex(parameterNames, name)];

                    try
                    {
                        // This could do complex things that may fail. Catch the exception.
                        await binder.SetValueAsync(argument, functionCancellationTokenSource.Token);
                    }
                    catch (OperationCanceledException)
                    {
                        throw;
                    }
                    catch (Exception exception)
                    {
                        string message = String.Format(CultureInfo.InvariantCulture,
                                                       "Error while handling parameter {0} after function returned:", name);
                        throw new InvalidOperationException(message, exception);
                    }
                }
            }

            if (singleton != null)
            {
                await singleton.ReleaseAsync(functionCancellationTokenSource.Token);
            }
        }