Inheritance: IJobExecutionContext
Exemplo n.º 1
0
        public void Execute(CancellationToken cancellationToken)
        {
            using (var connection = _storage.GetConnection())
                using (var fetchedJob = connection.FetchNextJob(_context.Queues, cancellationToken))
                {
                    try
                    {
                        var stateMachine = _stateMachineFactory.Create(connection);

                        using (var timeoutCts = new CancellationTokenSource(JobInitializationWaitTimeout))
                            using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
                                       cancellationToken,
                                       timeoutCts.Token))
                            {
                                var processingState = new ProcessingState(_context.ServerId, _context.WorkerNumber);

                                if (!stateMachine.ChangeState(
                                        fetchedJob.JobId,
                                        processingState,
                                        new[] { EnqueuedState.StateName, ProcessingState.StateName },
                                        linkedCts.Token))
                                {
                                    // We should re-queue a job identifier only when graceful shutdown
                                    // initiated.
                                    cancellationToken.ThrowIfCancellationRequested();

                                    // We should forget a job in a wrong state, or when timeout exceeded.
                                    fetchedJob.RemoveFromQueue();
                                    return;
                                }
                            }

                        // Checkpoint #3. Job is in the Processing state. However, there are
                        // no guarantees that it was performed. We need to re-queue it even
                        // it was performed to guarantee that it was performed AT LEAST once.
                        // It will be re-queued after the JobTimeout was expired.

                        var context = new ServerJobExecutionContext(
                            fetchedJob.JobId, connection, _context, cancellationToken);

                        var state = PerformJob(fetchedJob.JobId, connection, context);

                        if (state != null)
                        {
                            // Ignore return value, because we should not do anything when current state is not Processing.
                            stateMachine.ChangeState(fetchedJob.JobId, state, new[] { ProcessingState.StateName });
                        }

                        // Checkpoint #4. The job was performed, and it is in the one
                        // of the explicit states (Succeeded, Scheduled and so on).
                        // It should not be re-queued, but we still need to remove its
                        // processing information.

                        fetchedJob.RemoveFromQueue();

                        // Success point. No things must be done after previous command
                        // was succeeded.
                    }
                    catch (JobAbortedException)
                    {
                        fetchedJob.RemoveFromQueue();
                    }
                    catch (Exception ex)
                    {
                        Logger.DebugException("An exception occurred while processing a job. It will be re-queued.", ex);

                        fetchedJob.Requeue();
                        throw;
                    }
                }
        }
Exemplo n.º 2
0
        public void Execute(CancellationToken cancellationToken)
        {
            using (var connection = _storage.GetConnection())
            using (var fetchedJob = connection.FetchNextJob(_context.Queues, cancellationToken))
            {
                try
                {
                    var stateMachine = _stateMachineFactory.Create(connection);

                    using (var timeoutCts = new CancellationTokenSource(JobInitializationWaitTimeout))
                    using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
                        cancellationToken,
                        timeoutCts.Token))
                    {
                        var processingState = new ProcessingState(_context.ServerId, _context.WorkerNumber);

                        if (!stateMachine.ChangeState(
                            fetchedJob.JobId,
                            processingState,
                            new[] { EnqueuedState.StateName, ProcessingState.StateName },
                            linkedCts.Token))
                        {
                            // We should re-queue a job identifier only when graceful shutdown
                            // initiated.
                            cancellationToken.ThrowIfCancellationRequested();

                            // We should forget a job in a wrong state, or when timeout exceeded.
                            fetchedJob.RemoveFromQueue();
                            return;
                        }
                    }

                    // Checkpoint #3. Job is in the Processing state. However, there are
                    // no guarantees that it was performed. We need to re-queue it even
                    // it was performed to guarantee that it was performed AT LEAST once.
                    // It will be re-queued after the JobTimeout was expired.

                    var context = new ServerJobExecutionContext(
                        fetchedJob.JobId, connection, _context, cancellationToken);

                    var state = PerformJob(fetchedJob.JobId, connection, context);

                    if (state != null)
                    {
                        // Ignore return value, because we should not do anything when current state is not Processing.
                        stateMachine.ChangeState(fetchedJob.JobId, state, new[] { ProcessingState.StateName });
                    }

                    // Checkpoint #4. The job was performed, and it is in the one
                    // of the explicit states (Succeeded, Scheduled and so on).
                    // It should not be re-queued, but we still need to remove its
                    // processing information.

                    fetchedJob.RemoveFromQueue();

                    // Success point. No things must be done after previous command
                    // was succeeded.
                }
                catch (JobAbortedException)
                {
                    fetchedJob.RemoveFromQueue();
                }
                catch (Exception ex)
                {
                    Logger.DebugException("An exception occurred while processing a job. It will be re-queued.", ex);

                    fetchedJob.Requeue();
                    throw;
                }
            }
        }