public async Task <bool> HandleAsync(JobContextMessage message, CancellationToken cancellationToken)
        {
            try
            {
                logger.LogDebug("Getting task type from period end message.");
                var taskType = GetTask(message);
                logger.LogDebug("Got period end type now create the period end event.");
                var periodEndEvent = CreatePeriodEndEvent(taskType);
                logger.LogDebug($"Created period end event. Type: {periodEndEvent.GetType().Name}");
                periodEndEvent.JobId            = message.JobId;
                periodEndEvent.CollectionPeriod = new CollectionPeriod
                {
                    AcademicYear = Convert.ToInt16(GetMessageValue(message, JobContextMessageConstants.KeyValuePairs.CollectionYear)),
                    Period       = Convert.ToByte(GetMessageValue(message, JobContextMessageConstants.KeyValuePairs.ReturnPeriod))
                };

                logger.LogDebug($"Got period end event: {periodEndEvent.ToJson()}");

                var jobIdToWaitFor = message.JobId;

                if (taskType == PeriodEndTaskType.PeriodEndReports)
                {
                    var endpointInstance = await endpointInstanceFactory.GetEndpointInstance();

                    await endpointInstance.Publish(periodEndEvent);

                    logger.LogInfo(
                        $"Finished publishing the period end event. Name: {periodEndEvent.GetType().Name}, JobId: {periodEndEvent.JobId}, Collection Period: {periodEndEvent.CollectionPeriod.Period}-{periodEndEvent.CollectionPeriod.AcademicYear}.");
                }
                else if (taskType == PeriodEndTaskType.PeriodEndSubmissionWindowValidation)
                {
                    await RecordPeriodEndJob(taskType, periodEndEvent).ConfigureAwait(false);

                    var endpointInstance = await endpointInstanceFactory.GetEndpointInstance();

                    await endpointInstance.Publish(periodEndEvent);

                    logger.LogInfo(
                        $"Finished publishing the period end event. Name: {periodEndEvent.GetType().Name}, JobId: {periodEndEvent.JobId}, Collection Period: {periodEndEvent.CollectionPeriod.Period}-{periodEndEvent.CollectionPeriod.AcademicYear}.");
                }
                else
                {
                    var existingNonFailedJobId = await jobsDataContext.GetNonFailedDcJobId(GetJobType(taskType),
                                                                                           periodEndEvent.CollectionPeriod.AcademicYear, periodEndEvent.CollectionPeriod.Period);

                    if (existingNonFailedJobId.GetValueOrDefault() == 0)
                    {
                        await RecordPeriodEndJob(taskType, periodEndEvent).ConfigureAwait(false);

                        var endpointInstance = await endpointInstanceFactory.GetEndpointInstance();

                        await endpointInstance.Publish(periodEndEvent);

                        logger.LogInfo(
                            $"Finished publishing the period end event. Name: {periodEndEvent.GetType().Name}, JobId: {periodEndEvent.JobId}, Collection Period: {periodEndEvent.CollectionPeriod.Period}-{periodEndEvent.CollectionPeriod.AcademicYear}.");
                    }
                    else
                    {
                        jobIdToWaitFor = existingNonFailedJobId.GetValueOrDefault();
                        logger.LogWarning($"Job already exists, will not be published. Name: {periodEndEvent.GetType().Name}, JobId: {periodEndEvent.JobId}, Collection Period: {periodEndEvent.CollectionPeriod.Period}-{periodEndEvent.CollectionPeriod.AcademicYear}.");
                    }
                }

                // TODO: This is a temporary workaround to enable the PeriodEndStart and PeriodEndStop messages to return true as otherwise the service will
                // TODO: just hang as there is nothing implemented to handle the Start and Stop events and so the job status service will never get a completion and so this will never return true.
                // PV2-1345 will handle PeriodEndStart
                // PeriodEndStoppedEvent will be handled by the PeriodEndStoppedEventHandler which in turn is handled by the ProcessProviderMonthEndCommandHandler but we don't want to wait for it

                if (periodEndEvent is PeriodEndStoppedEvent ||
                    periodEndEvent is PeriodEndRequestReportsEvent)
                {
                    logger.LogDebug("Returning as this is either a PeriodEndStop or PeriodEndRequestReports event");
                    return(true);
                }

                if (periodEndEvent is PeriodEndStartedEvent periodEndStartedEvent)
                {
                    return(await jobStatusService.WaitForPeriodEndStartedToFinish(jobIdToWaitFor, cancellationToken));
                }

                if (periodEndEvent is PeriodEndRequestValidateSubmissionWindowEvent)
                {
                    return(await jobStatusService.WaitForPeriodEndSubmissionWindowValidationToFinish(jobIdToWaitFor, cancellationToken));
                }

                await jobStatusService.WaitForJobToFinish(jobIdToWaitFor, cancellationToken);

                return(true);
            }
            catch (Exception ex)
            {
                logger.LogError($"Failed to process job context message. Message: {message.ToJson()}", ex);
                throw;
            }
        }