Published on :
Administration INTERNAL_CREATION

Orchestrating and Testing SAS Viya Job Flows

This code is also available in: Deutsch Español Français
Awaiting validation
Attention : This code requires administrator privileges.
The script begins by defining a temporary SAS© program ('testprog') that simulates a business task, capable of randomly failing (`abort`) based on macro variables. Two jobs, 'demo1' and 'demo2', are created from this temporary program using the `%mv_createjob` macro, placing them in the '/Public/temp' folder (typically a CASLIB). A `work.inputjobs` dataset is built to provide specific parameters (`_program`, `macrovar1`, `macrovar2`, `flow_id`, `_contextName`) for each job execution within the flow. The `%mv_jobflow` macro is then called with this input dataset to launch the job flow in parallel (maximum concurrency of 2), specifying an output dataset (`work.results`) and a reference log file (`myjoblog`). The `raise_err=1` option is used to propagate errors at the system level, allowing for better management of job failures. The system return code (`syscc`) is displayed before and after the flow execution for monitoring. Finally, the content of the flow log (`myjoblog`) is displayed in the SAS© log, and the `%mp_assert` macro is used to check that `syscc` is non-zero, confirming that remote job failures are correctly reported. `syscc` is then reset at the end of the script.
Data Analysis

Type : INTERNAL_CREATION


Data is entirely generated internally. A temporary SAS program is dynamically created using a `_null_` DATA STEP writing to a `filename temp`. Input parameters for the job flow (`work.inputjobs`) are also created by an explicit DATA STEP. No external files or SASHELP datasets are directly read for the script's main data.

1 Code Block
DATA STEP Data
Explanation :
This SAS block creates a temporary file named `testprog` and writes a SAS program to it. This program is designed to simulate a business task that uses macro variables `&_program`, `&flow_id`, `&macrovar1`, and `&macrovar2`. It includes conditional logic where `abort` is triggered if a random value (`rand("uniform")`) is greater than 0.50, thus simulating a job failure. The program also generates an anonymous dataset containing calculated variables (`rval`, `rand`, `y`).
Copied!
1filename testprog temp;
2DATA _null_;
3 file testprog;
4 put '%put this is job: &_program;'
5 / '%put this was run in flow &flow_id;'
6 / 'data ;'
7 / ' rval=rand("uniform");'
8 / ' rand=rval*&macrovar1;'
9 / ' do x=1 to rand;'
10 / ' y=rand*&macrovar2;'
11 / ' if (rval>0.50) then abort;'
12 / ' else output;'
13 / ' end;'
14 / 'run;'
15 ;
16RUN;
2 Code Block
MACRO CALL (mv_createjob)
Explanation :
Calls the `%mv_createjob` macro to create a job named 'demo1'. This job is saved to the path '/Public/temp' (likely a folder in a CASLIB) and uses the SAS code generated in the temporary file `testprog` as its source. This macro prepares the job for subsequent execution within a job flow on the SAS Viya environment.
Copied!
1%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
3 Code Block
MACRO CALL (mv_createjob)
Explanation :
Calls the `%mv_createjob` macro again to create a second job named 'demo2', also using the same source code (`testprog`) and the same save path as job 'demo1'. This configures two independent jobs that will be managed by the same execution flow.
Copied!
1%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
4 Code Block
DATA STEP Data
Explanation :
This DATA STEP creates the `work.inputjobs` dataset. This dataset serves as a dashboard for the job flow, specifying execution parameters for each job instance. It sets the `_contextName` as 'SAS Job Execution compute context', iterates over two distinct `flow_id`s, and for each `flow_id`, prepares executions for 'demo1' and 'demo2' with different values for `macrovar1` and `macrovar2`. This allows testing job behavior with various inputs and simulating multiple executions.
Copied!
1DATA work.inputjobs;
2 _contextName='SAS Job Execution compute context';
3 DO flow_id=1 to 2;
4 DO i=1 to 4;
5 _program='/Public/temp/demo1';
6 macrovar1=10*i;
7 macrovar2=4*i;
8 OUTPUT;
9 i+1;
10 _program='/Public/temp/demo2';
11 macrovar1=40*i;
12 macrovar2=44*i;
13 OUTPUT;
14 END;
15 END;
16RUN;
5 Code Block
MACRO CALL (%put)
Explanation :
Displays the current value of the automatic variable `SYSCC` (System Return Code) in the SAS log. `SYSCC` contains the return code of the last system call or macro, serving here as a checkpoint before job flow execution to ensure a known initial state, typically 0 for success.
Copied!
1%put NOTE: &=syscc;
6 Code Block
MACRO CALL (mv_jobflow)
Explanation :
Calls the `%mv_jobflow` macro to execute the defined jobs. It takes `work.inputjobs` as the input dataset (`inds`), limits concurrency to 2 parallel jobs (`maxconcurrency=2`), saves results to `work.results` (`outds`), and log information to a fileref `myjoblog` (`outref`). The `raise_err=1` option is crucial because it ensures that errors occurring in the executed jobs are reflected in the `SYSCC` of the calling process, allowing for centralized error handling. `mdebug=1` enables debugging mode for the macro, providing detailed information in the log.
Copied!
1%mv_jobflow(inds=work.inputjobs
2 ,maxconcurrency=2
3 ,outds=work.results
4 ,outref=myjoblog
5 ,raise_err=1
6 ,mdebug=1
7)
7 Code Block
MACRO CALL (%put)
Explanation :
Displays the `SYSCC` value after job flow execution. This allows verifying if errors from internal jobs (which may `abort`) were correctly captured and transmitted to the calling process by the `%mv_jobflow` macro, and if `SYSCC` reflects a potential flow failure.
Copied!
1%put NOTE: &=syscc;
8 Code Block
DATA STEP
Explanation :
This DATA STEP reads the content of the file referenced by `myjoblog` (which was populated by the `%mv_jobflow` macro and contains the consolidated job flow log) and prints each line (`_infile_`) to the SAS log. This is an essential debugging and verification step to examine messages and statuses generated by jobs executed in the flow.
Copied!
1DATA _null_;
2 INFILE myjoblog;
3 INPUT; put _infile_;
4RUN;
9 Code Block
MACRO CALL (mp_assert)
Explanation :
Uses the `%mp_assert` macro (likely a custom test or assertion macro) to check a logical condition. Here, it ensures that the `SYSCC` variable is not equal to zero, which would indicate that an error was detected and propagated from the job flow. The `desc` message clarifies the objective: 'Check that a non-zero return code is returned if the called job fails'. This assertion is crucial for validating the robustness of the flow system's error handling.
Copied!
1%mp_assert(
2 iftrue=(&syscc ne 0),
3 desc=Check that non zero return code is returned IF called job fails
4)
10 Code Block
MACRO CALL (%let)
Explanation :
Resets the automatic macro variable `SYSCC` to zero. This practice is common at the end of a test or code section to prevent the `SYSCC` from this section from affecting subsequent checks or the overall state of the program being executed.
Copied!
1%let syscc=0;
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.