Example #1
0
        // This method runs concurrently with other index processing.
        // Ensure all logic here is idempotent.
        public void ProcessFunctionStarted(FunctionStartedMessage message)
        {
            FunctionInstanceSnapshot snapshot = CreateSnapshot(message);

            _functionInstanceLogger.LogFunctionStarted(snapshot);

            string              functionId         = new FunctionIdentifier(message.SharedQueueName, message.Function.Id).ToString();
            Guid                functionInstanceId = message.FunctionInstanceId;
            DateTimeOffset      startTime          = message.StartTime;
            WebJobRunIdentifier webJobRunId        = message.WebJobRunIdentifier;
            Guid?               parentId           = message.ParentId;

            // Race to write index entries for function started.
            if (!HasLoggedFunctionCompleted(functionInstanceId))
            {
                CreateOrUpdateIndexEntries(snapshot, startTime, webJobRunId);
            }

            // If the function has since completed, we lost the race.
            // Delete any function started index entries.
            // Note that this code does not depend on whether or not the index entries were previously written by this
            // method, as this processing could have been aborted and resumed at another point in time. In that case,
            // we still own cleaning up any dangling function started index entries.
            DateTimeOffset?functionCompletedTime      = GetFunctionCompletedTime(functionInstanceId);
            bool           hasLoggedFunctionCompleted = functionCompletedTime.HasValue;

            if (hasLoggedFunctionCompleted)
            {
                DeleteFunctionStartedIndexEntriesIfNeeded(functionInstanceId, message.StartTime,
                                                          functionCompletedTime.Value, functionId, parentId, webJobRunId);
            }
        }