| Quintiq file version 2.0 | 
| #parent: #root | 
| Method StartAfterPreprocessing () as stream[JSON] | 
| { | 
|   Description: | 
|   [* | 
|     Start optimization of this run. | 
|      | 
|     If the run is configured to execute in a single transaction (using `InOneTransaction`, the run wil do so without creating a transaction. When an error or rollback happens in this case, the transaction will be aborted. | 
|     You can still inspect the run in that case by clicking "Recover last run" in the optimizers form. | 
|   *] | 
|   TextBody: | 
|   [* | 
|     this.StartedOn( DateTime::ActualTime() ); | 
|     start_link := this.LinkStart(); | 
|     time := OS::PrecisionCounter(); | 
|      | 
|     result := null( stream[JSON] ); | 
|     if( this.InOneTransaction() ) | 
|     { | 
|       // Explicit propagate all, to make sure the behavior is identical to the run starting in another transaction. | 
|       Transaction::Transaction().Propagate(); | 
|        | 
|       nr_reactive_calls := LibOpt_CurrentTransaction::GetSpawnedReactiveCalls(); | 
|       transaction := LibOpt_CurrentTransaction::GetCurrentTransaction( this.Optimization() ); | 
|        | 
|       if( transaction.IsSafe() ) | 
|       { | 
|         istaskregistered := transaction.BeforeMethodCall_ExistingSafeTransaction( null( LibOpt_Task ) ); | 
|         // A user error might occur in LibOpt_TaskTransporterOneTransaction::Send or in other methods called by Send.  | 
|         // However, transaction.IsSafe() is true, so we are inside a try{...} block. We have also called BeforeMethodCall_ExistingSafeTransaction. The error is therefore handled gracefully.  | 
|         result := start_link.Execute( null( LibOpt_Task ), this.StartScope() ); | 
|         transaction.AfterMethodCall_ExistingSafeTransaction( null( LibOpt_Task ), istaskregistered );  | 
|       } | 
|       else | 
|       { | 
|         try | 
|         { | 
|           istaskregistered := transaction.BeforeMethodCall_TryBlock( null( LibOpt_Task ) ); | 
|           // A user error might occur in LibOpt_TaskTransporterOneTransaction::Send or in other methods called by Send.  | 
|           // However, we are inside a try{...} block. We have also called BeforeMethodCall_TryBlock. The error is therefore handled gracefully.  | 
|           result := start_link.Execute( null( LibOpt_Task ), this.StartScope() ); | 
|           transaction.AfterMethodCall_TryBlock( null( LibOpt_Task ), this, istaskregistered ); | 
|         } | 
|         onerror | 
|         { | 
|           this.IsFailed( true ); | 
|           transaction.OnError( e ); | 
|         } | 
|         onfailure | 
|         { | 
|           this.IsFailed( true ); | 
|           transaction.OnFailure( e ); | 
|         } | 
|       } | 
|        | 
|       if( LibOpt_CurrentTransaction::GetSpawnedReactiveCalls() = nr_reactive_calls ) | 
|       { | 
|         this.OnFinish(); | 
|       } | 
|       else | 
|       { | 
|         err_message := Translations::LibOpt_Run_NotRunningInOneTransaction( this, LibOpt_CurrentTransaction::GetSpawnedReactiveCallNames( time ) ); | 
|         err := construct( LibOpt_Error, GeneralInformation := err_message ); | 
|         LibOpt_SnapshotError::Throw( this, err ); | 
|         this.RollbackOneTransaction(); | 
|       } | 
|      | 
|     } | 
|     else | 
|     { | 
|       // The DatasetCopyConditional relation was not yet propagated because it depends on the Run.Optimization relation. | 
|       // This relation did not exist during the previous propagate, because the run object was only created right before this method is called. | 
|       // The DatasetCopyConditional relation is required when creating a dataset copy.  | 
|       Transaction::Transaction().Propagate( relation( LibOpt_BreakpointPosition, DatasetCopyConditional ) ); | 
|       result := start_link.Execute( null( LibOpt_Task ), this.StartScope() ); | 
|       handle_exception := result->Exception()->( e ) { this.IsFailed( true ) } | 
|       ignore_exception := result->IgnoreException(); | 
|       on_finish        := ignore_exception->|this->OnFinish(); | 
|       result := ignore_exception->Merge( handle_exception->|stream[JSON]::Success(), | 
|                                          on_finish->|stream[JSON]::Success() ); | 
|     } | 
|      | 
|     return result; | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |