Exemplo n.º 1
0
            public Task <FunctionResult> TryExecuteAsync(TriggeredFunctionData input, CancellationToken cancellationToken)
            {
                var e = ((ResilientEventHubData)input.TriggerValue).EventData;

                e.Properties.TryGetValue("ExceptionCount", out var count);

                if (e.Properties.TryGetValue("StopInvalidData", out var exc) && exc is bool bexc && bexc == true)
                {
                    return(Task.FromResult(new FunctionResult(false,
                                                              (Exception)typeof(EventSubscriberStopException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
                                                                                                                             new Type[] { typeof(Result) }, null)
                                                              .Invoke(new object[] { CreateResult(SubscriberStatus.InvalidData, null) }))));
                }

                if ((int)count > 0)
                {
                    e.Properties["ExceptionCount"] = (int)count - 1;
                    TotalError++;
                    return(Task.FromResult(new FunctionResult(false, new DivideByZeroException())));
                }
                else
                {
                    TotalSuccess++;
                    return(Task.FromResult(new FunctionResult(true)));
                }
            }
        internal async Task ProcessSessionMessageAsync(ProcessSessionMessageEventArgs args)
        {
            _concurrencyUpdateManager?.MessageProcessed();

            using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(args.CancellationToken, _cancellationTokenSource.Token))
            {
                var actions = new ServiceBusSessionMessageActions(args);
                if (!await _sessionMessageProcessor.Value.BeginProcessingMessageAsync(actions, args.Message, linkedCts.Token).ConfigureAwait(false))
                {
                    return;
                }

                ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateSingle(args.Message, actions, _client.Value);

                TriggeredFunctionData data   = input.GetTriggerFunctionData();
                FunctionResult        result = await _triggerExecutor.TryExecuteAsync(data, linkedCts.Token).ConfigureAwait(false);

                if (actions.ShouldReleaseSession)
                {
                    args.ReleaseSession();
                }

                await _sessionMessageProcessor.Value.CompleteProcessingMessageAsync(actions, args.Message, result, linkedCts.Token).ConfigureAwait(false);
            }
        }
 private async Task TryExecuteWithLoggingAsync(TriggeredFunctionData input, EventData message)
 {
     using (_logger.BeginScope(GetLinksScope(message)))
     {
         await _executor.TryExecuteAsync(input, _cts.Token).ConfigureAwait(false);
     }
 }
Exemplo n.º 4
0
        internal async Task InvokeJobFunction(DateTime lastOccurrence, bool isPastDue)
        {
            CancellationToken token = _cancellationTokenSource.Token;

            TimerInfo timerInfo = new TimerInfo(_attribute.Schedule);

            timerInfo.IsPastDue = isPastDue;

            TriggeredFunctionData input = new TriggeredFunctionData
            {
                // TODO: how to set this properly?
                ParentId     = null,
                TriggerValue = timerInfo
            };
            FunctionResult result = await _executor.TryExecuteAsync(input, token);

            if (!result.Succeeded)
            {
                token.ThrowIfCancellationRequested();
            }

            if (_attribute.UseMonitor)
            {
                DateTime nextOccurrence = _schedule.GetNextOccurrence(lastOccurrence);
                await _scheduleMonitor.UpdateAsync(_timerName, lastOccurrence, nextOccurrence);
            }
        }
Exemplo n.º 5
0
        internal async Task InvokeJobFunction(DateTime lastOccurrence, bool isPastDue = false)
        {
            CancellationToken     token     = _cancellationTokenSource.Token;
            TimerInfo             timerInfo = new TimerInfo(_attribute.Schedule, _scheduleStatus, isPastDue);
            TriggeredFunctionData input     = new TriggeredFunctionData
            {
                TriggerValue = timerInfo
            };

            try
            {
                FunctionResult result = await _executor.TryExecuteAsync(input, token);

                if (!result.Succeeded)
                {
                    token.ThrowIfCancellationRequested();
                }
            }
            catch
            {
                // We don't want any function errors to stop the execution
                // schedule. Errors will be logged to Dashboard already.
            }

            if (ScheduleMonitor != null)
            {
                _scheduleStatus = new ScheduleStatus
                {
                    Last = lastOccurrence,
                    Next = _schedule.GetNextOccurrence(lastOccurrence)
                };
                await ScheduleMonitor.UpdateStatusAsync(_timerName, _scheduleStatus);
            }
        }
Exemplo n.º 6
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var connectionString = Environment.GetEnvironmentVariable(_attribute.IotHubConnectionString);

            var serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

            var feedbackReceiver = serviceClient.GetFeedbackReceiver();

            _listening = true;

            while (_listening)
            {
                var feedbackBatch = await feedbackReceiver.ReceiveAsync();

                if (feedbackBatch == null)
                {
                    continue;
                }

                var triggerData = new TriggeredFunctionData
                {
                    TriggerValue = feedbackBatch
                };

                await _executor.TryExecuteAsync(triggerData, CancellationToken.None);

                await feedbackReceiver.CompleteAsync(feedbackBatch);
            }
        }
Exemplo n.º 7
0
        public async Task OnMessage(MqttMessageReceivedEventArgs arg)
        {
            var token = _cancellationTokenSource.Token;

            var triggeredFunctionData = new TriggeredFunctionData
            {
                TriggerValue = arg.Message
            };

            try
            {
                var result = await _executor.TryExecuteAsync(triggeredFunctionData, token).ConfigureAwait(false);

                if (!result.Succeeded)
                {
                    if (!token.IsCancellationRequested)
                    {
                        _logger.LogCritical("Error firing function", result.Exception);
                    }
                    token.ThrowIfCancellationRequested();
                }
            }
            catch (Exception e)
            {
                _logger.LogCritical("Error firing function", e);

                // We don't want any function errors to stop the execution. Errors will be logged to Dashboard already.
            }
        }
Exemplo n.º 8
0
        private IEnumerable <(TriggeredFunctionData messages, IEnumerable <string> ackIds)> getMessages(Task <BaseResponse <PullResponse> > pullTask)
        {
            var pull = pullTask.Result;

            if (pull != null && pull.Success && pull.Response.receivedMessages != null && pull.Response.receivedMessages.Count() > 0)
            {
                for (int i = 0; i < NumberOfMessageBlocks; i++)
                {
                    var messagesBlock = pull.Response.receivedMessages.Skip(i * triggerAttribute.MaxBatchSize).Take(triggerAttribute.MaxBatchSize);

                    IEnumerable <string> messages = messagesBlock.Select(c => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(c.message.data)));
                    IEnumerable <string> ackIds   = messagesBlock.Select(c => c.ackId);

                    TriggeredFunctionData input = new TriggeredFunctionData
                    {
                        TriggerValue = messages
                    };

                    yield return(input, ackIds);
                }
            }
            else
            {
                if (pull != null && (!pull.Success))
                {
                    throw new Exception(pull.ErrorText);
                }
            }
        }
Exemplo n.º 9
0
        private async Task ExecuteAsync(Notification notification, CancellationToken cancellationToken)
        {
            var trigger = JObject.FromObject(notification);
            var input   = new TriggeredFunctionData {
                TriggerValue = trigger
            };
            var result = await _executor.TryExecuteAsync(input, cancellationToken);

            string?error = null;

            if (result.Exception != null && !(result.Exception is OperationCanceledException))
            {
                _logger.LogError($"Exception during execution: {result.Exception}");
                error = (result.Exception.InnerException ?? result.Exception).Message;
            }

            if (trigger.ContainsKey("Call"))
            {
                // TODO: Can we somehow detect that PerperTriggerValueBinder was already invoked for this?
                var call           = (string)trigger["Call"] !;
                var callsCache     = _ignite.GetCache <string, CallData>("calls");
                var callDataResult = await callsCache.TryGetAsync(call);

                if (callDataResult.Success)
                {
                    var callData = callDataResult.Value;
                    callData.Finished = true;
                    callData.Error    = error;
                    await callsCache.ReplaceAsync(call, callData);
                }
            }
        }
Exemplo n.º 10
0
        internal async Task ProcessMessageAsync(ProcessMessageEventArgs args)
        {
            EnsureIsRunning();

            _concurrencyUpdateManager?.MessageProcessed();

            using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(args.CancellationToken, _cancellationTokenSource.Token))
            {
                var actions = new ServiceBusMessageActions(args);
                if (!await _messageProcessor.Value.BeginProcessingMessageAsync(actions, args.Message, linkedCts.Token).ConfigureAwait(false))
                {
                    return;
                }

                var receiveActions           = new ServiceBusReceiveActions(args);
                ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateSingle(args.Message, actions, receiveActions, _client.Value);

                TriggeredFunctionData data = input.GetTriggerFunctionData();

                FunctionResult result = await _triggerExecutor.TryExecuteAsync(data, linkedCts.Token).ConfigureAwait(false);

                try
                {
                    await _messageProcessor.Value.CompleteProcessingMessageAsync(actions, args.Message, result, linkedCts.Token)
                    .ConfigureAwait(false);
                }
                finally
                {
                    receiveActions.EndExecutionScope();
                }
            }
        }
        private async Task InvokeJobFunction(MqttApplicationMessageReceivedEventArgs mqttApplicationMessageReceivedEventArgs)
        {
            var token = _cancellationTokenSource.Token;

            var mqttInfo = new PublishedMqttMessage(
                mqttApplicationMessageReceivedEventArgs.ApplicationMessage.Topic,
                mqttApplicationMessageReceivedEventArgs.ApplicationMessage.Payload,
                mqttApplicationMessageReceivedEventArgs.ApplicationMessage.QualityOfServiceLevel.ToString(),
                mqttApplicationMessageReceivedEventArgs.ApplicationMessage.Retain);

            var triggeredFunctionData = new TriggeredFunctionData
            {
                TriggerValue = mqttInfo
            };

            try
            {
                var result = await _executor.TryExecuteAsync(triggeredFunctionData, token).ConfigureAwait(false);

                if (!result.Succeeded)
                {
                    if (!token.IsCancellationRequested)
                    {
                        _logger.LogCritical("Error firing function", result.Exception);
                    }
                    token.ThrowIfCancellationRequested();
                }
            }
            catch (Exception e)
            {
                _logger.LogCritical("Error firing function", e);

                // We don't want any function errors to stop the execution. Errors will be logged to Dashboard already.
            }
        }
Exemplo n.º 12
0
        private async Task ProcessPartitionItemsAsync(int partition, IEnumerable <IKafkaEventData> events, CancellationToken cancellationToken)
        {
            TopicPartition topicPartition = null;

            foreach (var kafkaEventData in events)
            {
                var triggerInput = KafkaTriggerInput.New(kafkaEventData);
                var triggerData  = new TriggeredFunctionData
                {
                    TriggerValue = triggerInput,
                };

                await this.ExecuteFunctionAsync(triggerData, cancellationToken);

                if (topicPartition == null)
                {
                    topicPartition = new TopicPartition(kafkaEventData.Topic, partition);
                }

                // Commiting after each function execution plays nicer with function scaler.
                // When processing a large batch of events where the execution of each event takes time
                // it would take Events_In_Batch_For_Partition * Event_Processing_Time to update the current offset.
                // Doing it after each event minimizes the delay
                this.Commit(new[] { new TopicPartitionOffset(topicPartition, kafkaEventData.Offset + 1) });  // offset is inclusive when resuming
            }
        }
        public override async Task <string> RunAsync(TaskContext context, string rawInput)
        {
            string instanceId   = context.OrchestrationInstance.InstanceId;
            var    inputContext = new DurableActivityContext(instanceId, rawInput);

            // TODO: Wire up the parent ID to improve dashboard logging.
            Guid?parentId     = null;
            var  triggerInput = new TriggeredFunctionData {
                ParentId = parentId, TriggerValue = inputContext
            };

            this.config.TraceHelper.FunctionStarting(
                this.config.HubName,
                this.activityName,
                this.activityVersion,
                instanceId,
                this.config.GetIntputOutputTrace(rawInput),
                functionType: FunctionType.Activity,
                isReplay: false);

            FunctionResult result = await this.executor.TryExecuteAsync(triggerInput, CancellationToken.None);

            if (!result.Succeeded)
            {
                // Flow the original activity function exception to the orchestration
                // without the outer FunctionInvocationException.
                Exception exceptionToReport = StripFunctionInvocationException(result.Exception);

                this.config.TraceHelper.FunctionFailed(
                    this.config.HubName,
                    this.activityName,
                    this.activityVersion,
                    instanceId,
                    exceptionToReport?.ToString() ?? string.Empty,
                    functionType: FunctionType.Activity,
                    isReplay: false);

                if (exceptionToReport != null)
                {
                    throw new TaskFailureException(
                              $"Activity function '{this.activityName}' failed: {exceptionToReport.Message}",
                              Utils.SerializeCause(exceptionToReport, MessagePayloadDataConverter.Default));
                }
            }

            string serializedOutput = inputContext.GetSerializedOutput();

            this.config.TraceHelper.FunctionCompleted(
                this.config.HubName,
                this.activityName,
                this.activityVersion,
                instanceId,
                this.config.GetIntputOutputTrace(serializedOutput),
                continuedAsNew: false,
                functionType: FunctionType.Activity,
                isReplay: false);

            return(serializedOutput);
        }
        /// <summary>
        /// Process the file indicated by the specified <see cref="FileSystemEventArgs"/>.
        /// </summary>
        /// <param name="eventArgs">The <see cref="FileSystemEventArgs"/> indicating the file to process.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
        /// <returns>
        /// A <see cref="Task"/> that returns true if the file was processed successfully, false otherwise.
        /// </returns>
        public virtual async Task <bool> ProcessFileAsync(FileSystemEventArgs eventArgs, CancellationToken cancellationToken)
        {
            try
            {
                string filePath = eventArgs.FullPath;
                using (StreamWriter statusWriter = AquireStatusFileLock(filePath, eventArgs.ChangeType))
                {
                    if (statusWriter == null)
                    {
                        return(false);
                    }

                    // write an entry indicating the file is being processed
                    StatusFileEntry status = new StatusFileEntry
                    {
                        State      = ProcessingState.Processing,
                        Timestamp  = DateTime.UtcNow,
                        LastWrite  = File.GetLastWriteTimeUtc(filePath),
                        ChangeType = eventArgs.ChangeType,
                        InstanceId = InstanceId
                    };
                    _serializer.Serialize(statusWriter, status);
                    statusWriter.WriteLine();

                    // invoke the job function
                    TriggeredFunctionData input = new TriggeredFunctionData
                    {
                        // TODO: set this properly
                        ParentId     = null,
                        TriggerValue = eventArgs
                    };
                    FunctionResult result = await _executor.TryExecuteAsync(input, cancellationToken);

                    if (result.Succeeded)
                    {
                        // write a status entry indicating processing is complete
                        status.State     = ProcessingState.Processed;
                        status.Timestamp = DateTime.UtcNow;
                        _serializer.Serialize(statusWriter, status);
                        statusWriter.WriteLine();
                        return(true);
                    }
                    else
                    {
                        // If the function failed, we leave the in progress status
                        // file as is (it will show "Processing"). The file will be
                        // reprocessed later on a clean-up pass.
                        statusWriter.Close();
                        cancellationToken.ThrowIfCancellationRequested();
                        return(false);
                    }
                }
            }
            catch
            {
                return(false);
            }
        }
Exemplo n.º 15
0
        public static async Task <WrappedFunctionResult> ExecuteFunctionInOrchestrationMiddleware(
            ITriggeredFunctionExecutor executor,
            TriggeredFunctionData triggerInput,
            DurableCommonContext context,
            CancellationToken cancellationToken)
        {
#pragma warning disable CS0618 // InvokeHandler approved for use by this extension
            if (triggerInput.InvokeHandler == null)
            {
                throw new ArgumentException(
                          $"{nameof(ExecuteFunctionInOrchestrationMiddleware)} should only be used when ${nameof(triggerInput)} has a value for ${nameof(TriggeredFunctionData.InvokeHandler)}");
            }

            try
            {
                context.ExecutorCalledBack = false;

                FunctionResult result = await executor.TryExecuteAsync(triggerInput, cancellationToken);

                if (context.ExecutorCalledBack)
                {
                    if (result.Succeeded)
                    {
                        return(WrappedFunctionResult.Success());
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(WrappedFunctionResult.FunctionRuntimeFailure(result.Exception));
                    }

                    return(WrappedFunctionResult.UserCodeFailure(result.Exception));
                }
                else
                {
                    // This can happen if the constructor for a non-static function fails.
                    // We want to treat this case exactly as if the function itself is throwing the exception.
                    // So we execute the middleware directly, instead of via the executor.
                    try
                    {
                        var exception = result.Exception ?? new InvalidOperationException("The function failed to start executing.");

                        await triggerInput.InvokeHandler(() => Task.FromException <object>(exception));

                        return(WrappedFunctionResult.Success());
                    }
                    catch (Exception e) when(!cancellationToken.IsCancellationRequested)
                    {
                        return(WrappedFunctionResult.UserCodeFailure(e));
                    }
                }
#pragma warning restore CS0618
            }
            catch (Exception e)
            {
                return(WrappedFunctionResult.FunctionRuntimeFailure(e));
            }
        }
Exemplo n.º 16
0
        private void OnCompleted()
        {
            var input = new TriggeredFunctionData
            {
                TriggerValue = new LiveProcessingStartedTriggerValue(null)
            };

            _executor.TryExecuteAsync(input, _cancellationToken).Wait();
        }
Exemplo n.º 17
0
        private void OnNotification(object sender, NpgsqlNotificationEventArgs e)
        {
            TriggeredFunctionData input = new TriggeredFunctionData
            {
                TriggerValue = e.AdditionalInformation
            };

            _executor.TryExecuteAsync(input, CancellationToken.None).RunSynchronously();
        }
Exemplo n.º 18
0
                public Task <FunctionResult> TryExecuteAsync(JObject data, CancellationToken cancellationToken)
                {
                    TriggeredFunctionData input = new TriggeredFunctionData
                    {
                        TriggerValue = data
                    };

                    return(_executor.TryExecuteAsync(input, cancellationToken));
                }
Exemplo n.º 19
0
        private void ProcessEvent(IEnumerable <ResolvedEvent> events)
        {
            TriggeredFunctionData input = new TriggeredFunctionData
            {
                TriggerValue = new EventStoreTriggerValue(events)
            };

            _executor.TryExecuteAsync(input, _cancellationToken).Wait();
        }
Exemplo n.º 20
0
            Task FunctionsMessageHandler(Message message, object userContext)
            {
                var input = new TriggeredFunctionData
                {
                    TriggerValue = message,
                };

                return(this.executor.TryExecuteAsync(input, CancellationToken.None));
            }
Exemplo n.º 21
0
        /// <summary>
        /// Invokes the job function.
        /// </summary>
        /// <param name="invocationTime">The time of the invocation, likely DateTime.Now.</param>
        /// <param name="isPastDue">True if the invocation is because the invocation is due to a past due timer.</param>
        /// <param name="runOnStartup">True if the invocation is because the timer is configured to run on startup.</param>
        internal async Task InvokeJobFunction(DateTime invocationTime, bool isPastDue = false, bool runOnStartup = false)
        {
            CancellationToken token           = _cancellationTokenSource.Token;
            ScheduleStatus    timerInfoStatus = null;

            if (ScheduleMonitor != null)
            {
                timerInfoStatus = ScheduleStatus;
            }
            TimerInfo             timerInfo = new TimerInfo(_schedule, timerInfoStatus, isPastDue);
            TriggeredFunctionData input     = new TriggeredFunctionData
            {
                TriggerValue = timerInfo
            };

            try
            {
                FunctionResult result = await _executor.TryExecuteAsync(input, token);

                if (!result.Succeeded)
                {
                    token.ThrowIfCancellationRequested();
                }
            }
            catch
            {
                // We don't want any function errors to stop the execution
                // schedule. Errors will be logged to Dashboard already.
            }

            // If the trigger fired before it was officially scheduled (likely under 1 second due to clock skew),
            // adjust the invocation time forward for the purposes of calculating the next occurrence.
            // Without this, it's possible to set the 'Next' value to the same time twice in a row,
            // which results in duplicate triggers if the site restarts.
            DateTime adjustedInvocationTime = invocationTime;

            if (!isPastDue && !runOnStartup && ScheduleStatus?.Next > invocationTime)
            {
                adjustedInvocationTime = ScheduleStatus.Next;
            }

            // Create the Last value with the adjustedInvocationTime; otherwise, the listener will
            // consider this a schedule change when the host next starts.
            ScheduleStatus = new ScheduleStatus
            {
                Last        = adjustedInvocationTime,
                Next        = _schedule.GetNextOccurrence(adjustedInvocationTime),
                LastUpdated = adjustedInvocationTime
            };

            if (ScheduleMonitor != null)
            {
                await ScheduleMonitor.UpdateStatusAsync(_timerName, ScheduleStatus);

                _logger.LogDebug($"Function '{_timerName}' updated status: Last='{ScheduleStatus.Last.ToString("o")}', Next='{ScheduleStatus.Next.ToString("o")}', LastUpdated='{ScheduleStatus.LastUpdated.ToString("o")}'");
            }
        }
Exemplo n.º 22
0
        private async Task ConnectionOnOnMessageReceived(SlackMessage message)
        {
            var triggerData = new TriggeredFunctionData
            {
                TriggerValue = message
            };

            await Executor.TryExecuteAsync(triggerData, CancellationToken.None);
        }
Exemplo n.º 23
0
        private async void OnMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
        {
            var triggerData = new TriggeredFunctionData
            {
                TriggerValue = e.ApplicationMessage
            };

            await Executor.TryExecuteAsync(triggerData, CancellationToken.None);
        }
        public static async Task <WrappedFunctionResult> ExecuteFunctionInOrchestrationMiddleware(
            ITriggeredFunctionExecutor executor,
            TriggeredFunctionData triggerInput,
            CancellationToken cancellationToken)
        {
#pragma warning disable CS0618 // InvokeHandler approved for use by this extension
            if (triggerInput.InvokeHandler == null)
            {
                throw new ArgumentException(
                          $"{nameof(ExecuteFunctionInOrchestrationMiddleware)} should only be used when ${nameof(triggerInput)} has a value for ${nameof(TriggeredFunctionData.InvokeHandler)}");
            }

            try
            {
                bool executedUserCode      = false;
                var  triggeredFunctionData = new TriggeredFunctionData()
                {
                    TriggerValue  = triggerInput.TriggerValue,
                    ParentId      = triggerInput.ParentId,
                    InvokeHandler = userCodeHandler =>
                    {
                        executedUserCode = true;
                        return(triggerInput.InvokeHandler(userCodeHandler));
                    },
#if !FUNCTIONS_V1
                    TriggerDetails = triggerInput.TriggerDetails,
#endif
                };
#pragma warning restore CS0618

                FunctionResult result = await executor.TryExecuteAsync(triggerInput, cancellationToken);

                if (result.Succeeded)
                {
                    return(WrappedFunctionResult.Success());
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return(WrappedFunctionResult.FunctionRuntimeFailure(result.Exception));
                }

                if (!executedUserCode)
                {
                    WrappedFunctionResult.UserCodeFailure(new InvalidOperationException(
                                                              "The function failed to start executing. " +
                                                              "For .NET functions, this can happen if an unhandled exception is thrown in the function's class constructor."));
                }

                return(WrappedFunctionResult.UserCodeFailure(result.Exception));
            }
            catch (Exception e)
            {
                return(WrappedFunctionResult.FunctionRuntimeFailure(e));
            }
        }
Exemplo n.º 25
0
        private void OnMessageArrived(RedisChannel channel, RedisValue value)
        {
            var triggerData = new TriggeredFunctionData
            {
                TriggerValue = value.ToString()
            };
            var task = _executor.TryExecuteAsync(triggerData, CancellationToken.None);

            task.Wait();
        }
Exemplo n.º 26
0
        public override async Task <string> RunAsync(TaskContext context, string rawInput)
        {
            string instanceId   = context.OrchestrationInstance.InstanceId;
            var    inputContext = new DurableActivityContext(instanceId, rawInput);

            // TODO: Wire up the parent ID to improve dashboard logging.
            Guid?parentId     = null;
            var  triggerInput = new TriggeredFunctionData {
                ParentId = parentId, TriggerValue = inputContext
            };

            this.config.TraceHelper.FunctionStarting(
                this.config.HubName,
                this.activityName,
                this.activityVersion,
                instanceId,
                this.config.GetIntputOutputTrace(rawInput),
                isOrchestrator: false,
                isReplay: false);

            FunctionResult result = await this.executor.TryExecuteAsync(triggerInput, CancellationToken.None);

            if (!result.Succeeded)
            {
                this.config.TraceHelper.FunctionFailed(
                    this.config.HubName,
                    this.activityName,
                    this.activityVersion,
                    instanceId,
                    result.Exception?.ToString() ?? string.Empty,
                    isOrchestrator: false,
                    isReplay: false);

                if (result.Exception != null)
                {
                    // Preserve the original exception context so that the durable task
                    // framework can report useful failure information.
                    ExceptionDispatchInfo.Capture(result.Exception).Throw();
                }
            }

            string serializedOutput = inputContext.GetSerializedOutput();

            this.config.TraceHelper.FunctionCompleted(
                config.HubName,
                this.activityName,
                this.activityVersion,
                instanceId,
                this.config.GetIntputOutputTrace(serializedOutput),
                continuedAsNew: false,
                isOrchestrator: false,
                isReplay: false);

            return(serializedOutput);
        }
Exemplo n.º 27
0
        protected override async Task ReaderAsync(ChannelReader <IKafkaEventData[]> reader, CancellationToken cancellationToken, ILogger logger)
        {
            var pendingTasks = new List <Task <FunctionResult> >();

            while (!cancellationToken.IsCancellationRequested && await reader.WaitToReadAsync(cancellationToken))
            {
                while (!cancellationToken.IsCancellationRequested && reader.TryRead(out var itemsToExecute))
                {
                    try
                    {
                        // Execute multiple topic in parallel.
                        // Order in a partition must be followed.
                        var partitionOffsets = new Dictionary <int, long>();
                        var itemsByPartition = itemsToExecute.GroupBy(x => x.Partition);

                        var i = 0;
                        do
                        {
                            pendingTasks.Clear();

                            foreach (var partition in itemsByPartition)
                            {
                                var kafkaEventData = partition.ElementAtOrDefault(i);
                                if (kafkaEventData != null)
                                {
                                    var triggerInput = KafkaTriggerInput.New(kafkaEventData);
                                    var triggerData  = new TriggeredFunctionData
                                    {
                                        TriggerValue = triggerInput,
                                    };

                                    partitionOffsets[partition.Key] = kafkaEventData.Offset + 1;  // offset is inclusive when resuming

                                    pendingTasks.Add(this.ExecuteFunctionAsync(triggerData, cancellationToken));
                                }
                            }

                            i++;
                            await Task.WhenAll(pendingTasks);
                        } while (!cancellationToken.IsCancellationRequested && pendingTasks.Count > 0);

                        if (!cancellationToken.IsCancellationRequested)
                        {
                            this.Commit(partitionOffsets.Select((kv) => new TopicPartitionOffset(new TopicPartition(itemsToExecute[0].Topic, kv.Key), kv.Value)));
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"Error in executor reader");
                    }
                }
            }

            logger.LogInformation("Exiting reader {processName}", nameof(SingleItemFunctionExecutor <TKey, TValue>));
        }
Exemplo n.º 28
0
                private void OnTimer(object sender, System.Timers.ElapsedEventArgs e)
                {
                    // TODO: When you receive new events from your event source,
                    // invoke the function executor
                    TriggeredFunctionData input = new TriggeredFunctionData
                    {
                        TriggerValue = new SampleTriggerValue()
                    };

                    _executor.TryExecuteAsync(input, CancellationToken.None).Wait();
                }
        private Task OnFileWatcher(IFileItem file, object obj)
        {
            ApiHubFile apiHubFile = new ApiHubFile(file);

            TriggeredFunctionData input = new TriggeredFunctionData
            {
                TriggerValue = apiHubFile
            };

            return(_executor.TryExecuteAsync(input, CancellationToken.None));
        }
        public async Task <FunctionResult> ExecuteAsync(Message value, CancellationToken cancellationToken)
        {
            Guid?parentId = ServiceBusCausalityHelper.GetOwner(value);
            TriggeredFunctionData input = new TriggeredFunctionData
            {
                ParentId     = parentId,
                TriggerValue = value
            };

            return(await _innerExecutor.TryExecuteAsync(input, cancellationToken));
        }