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' } 
 | 
} 
 |