Пример #1
0
        public Task <int> ReportExecutionTimeAsync(string payloadType, long durationMilliseconds, int timeoutMilliseconds)
        {
            CheckNotDisposedOrThrow();
            CheckRunningOrThrow();

            if (payloadType == null)
            {
                throw new ArgumentNullException(nameof(payloadType));
            }

            mLogger.DebugFormat("Execution time {0} reported for payload {1}",
                                durationMilliseconds,
                                payloadType);

            long requestId = Interlocked.Increment(ref mLastRequestId);

            StandardExecutionPerformanceMonitorWriteRequest processRequest =
                new StandardExecutionPerformanceMonitorWriteRequest(requestId,
                                                                    payloadType,
                                                                    durationMilliseconds,
                                                                    timeoutMilliseconds: timeoutMilliseconds,
                                                                    maxFailCount: 3);

            mStatsProcessingQueue.Add(processRequest);
            IncrementPerfMonPostCount();

            return(processRequest.Task.WithCleanup((prev) =>
            {
                if (processRequest.IsTimedOut)
                {
                    IncrementPerfMonWriteRequestTimeoutCount();
                }
                processRequest.Dispose();
            }));
        }
Пример #2
0
		private ITaskExecutor ResolveTaskExecutor ( IQueuedTask queuedTask )
		{
			Type payloadType;
			ITaskExecutor taskExecutor = null;

			if ( ( payloadType = DetectTaskPayloadType( queuedTask ) ) != null )
			{
				mLogger.DebugFormat( "Runtime payload type {0} found for task type {1}.",
					payloadType,
					queuedTask.Type );

				taskExecutor = mExecutorRegistry
					.ResolveExecutor( payloadType );

				if ( taskExecutor != null )
					mLogger.DebugFormat( "Executor {0} found for task type {1}.",
						taskExecutor.GetType().FullName,
						queuedTask.Type );
				else
					mLogger.WarnFormat( "Executor not found for task type {0}.",
						queuedTask.Type );

			}
			else
				mLogger.WarnFormat( "Runtime payload type not found for task type {0}.",
					queuedTask.Type );

			return taskExecutor;
		}
Пример #3
0
        private async Task DoStartupSequenceAsync()
        {
            mLogger.DebugFormat("Attempting to start the task engine with {0} workers",
                                mOptions.WorkerCount);

            string[] requiredPayloadTypes =
                GetRequiredPayloadTypeNames();

            mLogger.DebugFormat("Found payload types: {0}.",
                                string.Join(",", requiredPayloadTypes));

            //Start the task poller and then start workers
            await StartResultQueueProcessingAsync();
            await StartExecutionPerformanceMonitorAsync();
            await StartPollerAsync(requiredPayloadTypes);
            await StartWorkersAsync(requiredPayloadTypes);

            mLogger.Debug("The task engine has been successfully started.");
        }
        public Task ExecuteAsync(ComputeFactorial payload, ITaskExecutionContext executionContext)
        {
            long result = 1;

            if (payload.ForN > 0)
            {
                for (int i = 1; i <= payload.ForN; i++)
                {
                    result = result * i;
                }
            }

            mLogger.DebugFormat("Factorial for {0} = {1}",
                                payload.ForN,
                                result);

            TestExecutorEventBus <ComputeFactorial> .Instance
            .NotifyExecutorCompleted();

            return(Task.CompletedTask);
        }
Пример #5
0
        private async Task CleanupSignalingConnectionAsync(NpgsqlConnection signalingConn)
        {
            if (signalingConn != null)
            {
                mLogger.DebugFormat("Signalling connection state is {0}",
                                    signalingConn.FullState.ToString());

                if (signalingConn.IsListening(mNewTaskNotificationChannelName))
                {
                    await signalingConn.UnlistenAsync(mNewTaskNotificationChannelName, HandleTaskUpdateReceived);
                }

                if (signalingConn.IsConnectionSomewhatOpen())
                {
                    await signalingConn.CloseAsync();
                }

                signalingConn.Dispose();
            }
            else
            {
                mLogger.Debug("Connection was null. Nothing to perform.");
            }
        }
Пример #6
0
 private void HandlePollForDequeueRequired(object sender, ClearForDequeueEventArgs e)
 {
     mLogger.DebugFormat("Received poll for dequeue required notification from queue. Reason = {0}. Will resume polling...", e.Reason);
     mWaitForClearToDequeue.Set();
 }
        public async Task <IQueuedTaskToken> DequeueAsync(params string[] selectTaskTypes)
        {
            NpgsqlConnection          conn               = null;
            QueuedTask                dequeuedTask       = null;
            QueuedTaskResult          dequeuedTaskResult = null;
            PostgreSqlQueuedTaskToken dequeuedTaskToken  = null;

            MonotonicTimestamp startDequeue;
            DateTimeOffset     refNow = mTimestampProvider.GetNow();

            CheckNotDisposedOrThrow();

            try
            {
                mLogger.DebugFormat("Begin dequeue task. Looking for types: {0}.",
                                    string.Join <string>(",", selectTaskTypes));

                startDequeue = MonotonicTimestamp
                               .Now();

                conn = await OpenQueueConnectionAsync();

                if (conn == null)
                {
                    return(null);
                }

                using (NpgsqlTransaction tx = conn.BeginTransaction(IsolationLevel.ReadCommitted))
                {
                    //1. Dequeue means that we acquire lock on a task in the queue
                    //	with the guarantee that nobody else did, and respecting
                    //	the priority and static locks (basically the task_locked_until which says
                    //	that it should not be pulled out of the queue until the
                    //	current abstract time reaches that tick value)
                    dequeuedTask = await TryDequeueTaskAsync(selectTaskTypes, refNow, conn, tx);

                    if (dequeuedTask != null)
                    {
                        //2. Mark the task as being "Processing" and pull result info
                        //	The result is stored separately and it's what allows us to remove
                        //	the task from the queue at step #2,
                        //	whils also tracking it's processing status and previous results
                        dequeuedTaskResult = await TryUpdateTaskResultAsync(dequeuedTask, conn, tx);

                        if (dequeuedTaskResult != null)
                        {
                            await tx.CommitAsync();

                            dequeuedTaskToken = new PostgreSqlQueuedTaskToken(dequeuedTask,
                                                                              dequeuedTaskResult,
                                                                              refNow);
                        }
                    }

                    if (dequeuedTaskToken != null)
                    {
                        IncrementDequeueCount(MonotonicTimestamp.Since(startDequeue));
                    }
                    else
                    {
                        await tx.RollbackAsync();
                    }
                }
            }
            finally
            {
                if (conn != null)
                {
                    await conn.CloseAsync();

                    conn.Dispose();
                }
            }

            return(dequeuedTaskToken);
        }