hongji.li
2023-11-07 1a1ba3ad5ed9e4380185aa1ccad20204a0e5f115
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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' }
}