//Task.Status (Draft -> Requested -> Received -> Accepted -> Rejected -> // Ready -> Cancelled -> In Progress -> On Hold -> // Failed -> Completed -> Entered in Error) public Task.TaskStatus Run(Task Task) { try { //Task.TaskStatus? LocalTaskStatus = null; Task.ExecutionPeriod = new Period(); Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now); //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it. //If this fails do nothing as we are to asume some other process is workng on this task, just return InProgress. if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, Task)) { return(Task.TaskStatus.InProgress); } Task.Output = new List <Task.OutputComponent>(); if (!ProcessCompartmentDefinitionList(Task)) { using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { Task.ExecutionPeriod.EndElement = new FhirDateTime(DateTimeOffset.Now); IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.Failed, Task); Transaction.Commit(); } } return(Task.Status.Value); } catch (Exception Exec) { ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " + $"Task reference was: {Task.ResourceType.GetLiteral()}/{Task.Id}/_history/{Task.VersionId} The Task was not processed."); return(Task.TaskStatus.Failed); } }
public Task.TaskStatus Run(Task Task) { _Task = Task; IGlobalProperties.ServerReadOnlyMode = true; IGlobalProperties.ServerReadOnlyModeMessage = "The server is currently running a first time start-up task which loads all the base FHIR " + "specification search parameter resources as active search indexes within the Pyro FHIR server. " + $"This Task can be monitored by performing a GET on the servers Task endpoint for the Id of '{_Task.Id}'. " + $"For example: 'GET [base]/Task/{_Task.Id}'. While this Task is in progress the server can not allow resource writes " + $"to the server as these resources would not have their search parameter values indexed. Only once the Task is finished " + $"and all base search parameters are loaded will the server automatically switch out of read only mode. "; _SearchParameterResourceProcessedIdList = new List <string>(); try { _Task.ExecutionPeriod = new Period(); _Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now); //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it. //If this fails do nothing as we are to assume some other process is working on this task, just return InProgress. if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, _Task)) { IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); return(Task.TaskStatus.InProgress); } SetParametersBeforeRunningTaskLoad(_Task); _Task.Output = new List <Task.OutputComponent>(); //We process each file in the zip one at a time and commit and update the Task each time. //Once the IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed we then return, or return is the Load retunes false. while (_CurrentTaskStatus == Task.TaskStatus.InProgress) { _SearchParameterBundle = LoadFromZip(); if (_SearchParameterBundle != null) { TotalCounter = 0; int CommitBlockCounter = 0; IGlobalProperties.ServerReadOnlyModeMessage = SetServerReadOnlyMessage(0, _SearchParameterBundle.Entry.Count, _Task.Id); foreach (var Entry in _SearchParameterBundle.Entry) { TotalCounter++; IGlobalProperties.ServerReadOnlyModeMessage = SetServerReadOnlyMessage(TotalCounter, _SearchParameterBundle.Entry.Count, _Task.Id); if (Entry.Resource != null) { if (Entry.Resource is SearchParameter SearchParam) { if (!_SearchParameterResourceProcessedIdList.Contains(SearchParam.Id)) { //Increment Counter end of loop CommitBlockCounter++; using (DbContextTransaction TransactionSet = IUnitOfWork.BeginTransaction()) { try { _ResourceIdInProgress = SearchParam.Id; AddSearchParameterResourceToServer(SearchParam); if (FilterSearchParametersToSet(SearchParam)) { if (!SetSearchParameterServerIndex(SearchParam.Id)) { IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); throw new Exception("Failed to Set index!"); } } _SearchParameterResourceProcessedIdList.Add(_ResourceIdInProgress); TransactionSet.Commit(); } catch (Exception Exec) { TransactionSet.Rollback(); using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { _InErrorMessage = Exec.Message; _ResourceIdInError = _ResourceIdInProgress; _CurrentTaskStatus = Task.TaskStatus.Failed; SetParametersOnFailedTaskLoad(_Task); IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task); Transaction.Commit(); break; } } } } } else { string Message = "Internal Server Error: The search-parameter.xml file contained a non SearchParameter Resource Type as an entry, found type {Entry.Resource.TypeName}."; using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { _InErrorMessage = Message; SetParametersOnFailedTaskLoad(_Task); IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task); Transaction.Commit(); } IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); throw new Exception(Message); } } else { string Message = $"Internal Server Error: The search-parameter.xml file contained a null resource entry."; using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { _InErrorMessage = Message; SetParametersOnFailedTaskLoad(_Task); IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task); Transaction.Commit(); } IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); throw new Exception(Message); } //After each blockSize Commit the current progress to the Task //It is ok if we process SearchParameters that have already been processed as all that will happen is the //SearchParameter Resource will be Updated and the SearchIndex will not be set again. if (CommitBlockCounter == _TaskCommitBlockSize) { using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { SetParametersInProgressTaskLoad(_Task); IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task); Transaction.Commit(); } CommitBlockCounter = 0; } } //Finished all so mark as Completed if (_CurrentTaskStatus == Task.TaskStatus.InProgress) { ProcessCompositeSearchParameters(); using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { SetParametersOnCompletedTaskLoad(_Task); IFhirTaskTool.UpdateTaskAsStatus(_Task.Status.Value, _Task); Transaction.Commit(); _CurrentTaskStatus = Task.TaskStatus.Completed; IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); } } } } return(_CurrentTaskStatus); } catch (Exception Exec) { ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " + $"Task reference was: {_Task.ResourceType.GetLiteral()}/{_Task.Id}/_history/{_Task.VersionId} The Task was not processed."); IGlobalProperties.ServerReadOnlyMode = false; ICacheClear.ClearCache(); return(Task.TaskStatus.Failed); } }
//Task.Status (Draft -> Requested -> Received -> Accepted -> Rejected -> // Ready -> Cancelled -> In Progress -> On Hold -> // Failed -> Completed -> Entered in Error) public Task.TaskStatus Run(Task Task) { try { //Task.TaskStatus? LocalTaskStatus = null; Task.ExecutionPeriod = new Period(); Task.ExecutionPeriod.StartElement = new FhirDateTime(DateTimeOffset.Now); //Update the status of the task so that no other processes (instances of the server) also try and process this task can start it. //If this fails do nothing as we are to assume some other process is working on this task, just return InProgress. if (!IFhirTaskTool.UpdateTaskAsStatus(Task.TaskStatus.InProgress, Task)) { return(Task.TaskStatus.InProgress); } SetParametersBeforeRunningTaskLoad(Task); Task.Output = new List <Task.OutputComponent>(); //We process each file in the zip one at a time and commit and update the Task each time. //Once the IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed we then return, or return is the Load retunes false. while (IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Task.TaskStatus.InProgress) { bool AllOk = false; using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { AllOk = LoadFromZip(IFhirSpecificationDefinitionLoaderParameters); if (AllOk) { if (IFhirSpecificationDefinitionLoaderParameters.TaskStatus != Task.TaskStatus.Completed) { //Still InProgress so update this file status and commit this Bundle Transaction and update the Task //Then loop again for the next file SetParametersInProgressTaskLoad(Task); IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task); Transaction.Commit(); } else if (IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Task.TaskStatus.Completed) { //AllOk was True so IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed //All finished set the Whole Task to Completed and set the Completed end timestamps to the Task and Commit //The Break out of loop SetParametersOnCompletedTaskLoad(Task); IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task); Transaction.Commit(); break; } else { //What went wrong, when SetParametersInProgressTaskLoad(Task) retunes True the TaskStatus must always be Completed throw new Exception("Internal Server Error: SetParametersInProgressTaskLoad(Task) returned True yet TaskStatus was not Completed."); } } else { //Roll-back the failed transaction, we will update the Task as failed //in a separate transaction below Transaction.Rollback(); } } //Update the Task as Failed in new Transaction if (!AllOk) { SetParametersOnFailedTaskLoad(Task); using (DbContextTransaction Transaction = IUnitOfWork.BeginTransaction()) { IFhirTaskTool.UpdateTaskAsStatus(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value, Task); Transaction.Commit(); return(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value); } } } //AllOk was True so IFhirSpecificationDefinitionLoaderParameters.TaskStatus == Completed return(IFhirSpecificationDefinitionLoaderParameters.TaskStatus.Value); } catch (Exception Exec) { ILog.Error(Exec, $"Internal Server Error: Transaction was rolled back. " + $"Task reference was: {Task.ResourceType.GetLiteral()}/{Task.Id}/_history/{Task.VersionId} The Task was not processed."); return(Task.TaskStatus.Failed); } }