From 4ee13c9389b2e18ab8961db5bf720488b1735e3a Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Tue, 11 May 2021 20:25:39 +0300 Subject: [PATCH] fix: 400 log repeat, refactor mp_abort abortions, updated doc header --- all.sas | 89 ++++++++++++++++++++++++++++--------------- base/mp_abort.sas | 82 ++++++++++++++++++++++++--------------- viya/mv_getjoblog.sas | 7 +++- 3 files changed, 116 insertions(+), 62 deletions(-) diff --git a/all.sas b/all.sas index 9c3b333..b73f606 100644 --- a/all.sas +++ b/all.sas @@ -1624,13 +1624,24 @@ Usage: @details Configures an abort mechanism according to site specific policies or the particulars of an environment. For instance, can stream custom results back to the client in an STP Web App context, or completely stop - in the case of a batch run. + in the case of a batch run. For STP sessions + + The method used varies according to the context. Important points: + + @li should not use endsas or abort cancel in 9.4m3 environments as this can + cause hung multibridge sessions and result in a frozen STP server + @li should not use endsas in viya 3.5 as this destroys the session and cannot + fetch results (although both mv_getjoblog.sas and the @sasjs/adapter will + recognise this and fetch the log of the parent session instead) + @li STP environments must finish cleanly to avoid the log being sent to + _webout. To assist with this, we also run stpsrvset('program error', 0) + and set SYSCC=0. For 9.4m3 we take a unique approach - we open a macro + but don't close it! This provides a graceful abort, EXCEPT when called + called within a %include within a macro. See tests/mp_abort.test.1 for an + example case. + If you know of another way to gracefully abort a 9.4m3 STP session, we'd + love to hear about it! - Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored - Process environments. This macro takes a unique approach - we set the SAS - syscc to 0, run `stpsrvset('program error', 0)` (if SAS 9) and then - we open - a macro but don't close it! This provides a graceful abort for SAS web - services in all web enabled environments. @param mac= to contain the name of the calling macro @param msg= message to be returned @@ -1748,43 +1759,54 @@ Usage: if debug ge '"131"' then put '>>weboutEND<<'; run; + %put _all_; + %if "&sysprocessmode " = "SAS Stored Process Server " %then %do; data _null_; putlog 'stpsrvset program error and syscc'; rc=stpsrvset('program error', 0); call symputx("syscc",0,"g"); run; - endsas; + %if "%substr(&sysvlong.xxxxxxxxx,1,9)" ne "9.04.01M3" %then %do; + %put NOTE: Ending SAS session due to:; + %put NOTE- &msg; + endsas; + %end; %end; %else %if "&sysprocessmode " = "SAS Compute Server " %then %do; /* endsas kills the session making it harder to fetch results */ data _null_; - abort; + syswarningtext=symget('syswarningtext'); + syserrortext=symget('syserrortext'); + abort_msg=symget('msg'); + syscc=symget('syscc'); + sysuserid=symget('sysuserid'); + iftrue=symget('iftrue'); + put (_all_)(/=); + abort cancel nolist; run; %end; - %else %if "%substr(&sysvlong.xxxxxxxxx,1,9)" ne "9.04.01M3" %then %do; - %put NOTE: Ending SAS session due to:; - %put NOTE- &msg; - endsas; + %else %if "%substr(&sysvlong.xxxxxxxxx,1,9)" = "9.04.01M3" %then %do; + /** + * endsas kills 9.4m3 deployments by orphaning multibridges. + * Abort variants are ungraceful (non zero return code) + * This approach lets SAS run silently until the end :-) + * Caution - fails when called within a %include within a macro + * See tests/mp_abort.test.1 for an example case. + */ + filename skip temp; + data _null_; + file skip; + put '%macro skip();'; + comment '%mend skip; -> fix lint '; + put '%macro skippy();'; + comment '%mend skippy; -> fix lint '; + run; + %inc skip; + %end; + %else %do; + %abort cancel; %end; - - /** - * endsas is reliable but kills 9.4m3 deployments by hanging multibridges. - * Abort variants are ungraceful (non zero return code) - * This approach lets SAS run silently until the end :-) - * Caution - fails when called within a %include within a macro - * See tests/mp_abort.test.1 for an example case. - */ - %put _all_; - filename skip temp; - data _null_; - file skip; - put '%macro skip();'; - comment '%mend skip; -> fix lint '; - put '%macro skippy();'; - comment '%mend skippy; -> fix lint '; - run; - %inc skip; %end; %else %do; %put _all_; @@ -15310,10 +15332,12 @@ proc http method='GET' out=&fname1 &oauth_bearer %end; ; run; + %if &mdebug=1 %then %do; %put &sysmacroname: fetching log content from &base_uri&logloc/content; data _null_;infile &fname1;input;putlog _infile_;run; %end; + %if &SYS_PROCHTTP_STATUS_CODE=400 %then %do; /* fetch log from parent session */ %let logloc=%substr(&logloc,1,%index(&logloc,%str(/jobs/))-1); @@ -15331,9 +15355,12 @@ run; data _null_;infile &fname1;input;putlog _infile_;run; %end; %end; + %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do; - data _null_;infile &fname1;input;putlog _infile_;run; + %if &mdebug ne 1 %then %do; /* have already output above */ + data _null_;infile &fname1;input;putlog _infile_;run; + %end; %mp_abort(mac=&sysmacroname ,msg=%str(logfetch: &SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) ) diff --git a/base/mp_abort.sas b/base/mp_abort.sas index 4c5ea00..f8189b1 100644 --- a/base/mp_abort.sas +++ b/base/mp_abort.sas @@ -4,13 +4,24 @@ @details Configures an abort mechanism according to site specific policies or the particulars of an environment. For instance, can stream custom results back to the client in an STP Web App context, or completely stop - in the case of a batch run. + in the case of a batch run. For STP sessions + + The method used varies according to the context. Important points: + + @li should not use endsas or abort cancel in 9.4m3 environments as this can + cause hung multibridge sessions and result in a frozen STP server + @li should not use endsas in viya 3.5 as this destroys the session and cannot + fetch results (although both mv_getjoblog.sas and the @sasjs/adapter will + recognise this and fetch the log of the parent session instead) + @li STP environments must finish cleanly to avoid the log being sent to + _webout. To assist with this, we also run stpsrvset('program error', 0) + and set SYSCC=0. For 9.4m3 we take a unique approach - we open a macro + but don't close it! This provides a graceful abort, EXCEPT when called + called within a %include within a macro. See tests/mp_abort.test.1 for an + example case. + If you know of another way to gracefully abort a 9.4m3 STP session, we'd + love to hear about it! - Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored - Process environments. This macro takes a unique approach - we set the SAS - syscc to 0, run `stpsrvset('program error', 0)` (if SAS 9) and then - we open - a macro but don't close it! This provides a graceful abort for SAS web - services in all web enabled environments. @param mac= to contain the name of the calling macro @param msg= message to be returned @@ -128,43 +139,54 @@ if debug ge '"131"' then put '>>weboutEND<<'; run; + %put _all_; + %if "&sysprocessmode " = "SAS Stored Process Server " %then %do; data _null_; putlog 'stpsrvset program error and syscc'; rc=stpsrvset('program error', 0); call symputx("syscc",0,"g"); run; - endsas; + %if "%substr(&sysvlong.xxxxxxxxx,1,9)" ne "9.04.01M3" %then %do; + %put NOTE: Ending SAS session due to:; + %put NOTE- &msg; + endsas; + %end; %end; %else %if "&sysprocessmode " = "SAS Compute Server " %then %do; /* endsas kills the session making it harder to fetch results */ data _null_; - abort; + syswarningtext=symget('syswarningtext'); + syserrortext=symget('syserrortext'); + abort_msg=symget('msg'); + syscc=symget('syscc'); + sysuserid=symget('sysuserid'); + iftrue=symget('iftrue'); + put (_all_)(/=); + abort cancel nolist; run; %end; - %else %if "%substr(&sysvlong.xxxxxxxxx,1,9)" ne "9.04.01M3" %then %do; - %put NOTE: Ending SAS session due to:; - %put NOTE- &msg; - endsas; + %else %if "%substr(&sysvlong.xxxxxxxxx,1,9)" = "9.04.01M3" %then %do; + /** + * endsas kills 9.4m3 deployments by orphaning multibridges. + * Abort variants are ungraceful (non zero return code) + * This approach lets SAS run silently until the end :-) + * Caution - fails when called within a %include within a macro + * See tests/mp_abort.test.1 for an example case. + */ + filename skip temp; + data _null_; + file skip; + put '%macro skip();'; + comment '%mend skip; -> fix lint '; + put '%macro skippy();'; + comment '%mend skippy; -> fix lint '; + run; + %inc skip; + %end; + %else %do; + %abort cancel; %end; - - /** - * endsas is reliable but kills 9.4m3 deployments by hanging multibridges. - * Abort variants are ungraceful (non zero return code) - * This approach lets SAS run silently until the end :-) - * Caution - fails when called within a %include within a macro - * See tests/mp_abort.test.1 for an example case. - */ - %put _all_; - filename skip temp; - data _null_; - file skip; - put '%macro skip();'; - comment '%mend skip; -> fix lint '; - put '%macro skippy();'; - comment '%mend skippy; -> fix lint '; - run; - %inc skip; %end; %else %do; %put _all_; diff --git a/viya/mv_getjoblog.sas b/viya/mv_getjoblog.sas index dc44c9b..1db9896 100644 --- a/viya/mv_getjoblog.sas +++ b/viya/mv_getjoblog.sas @@ -241,10 +241,12 @@ proc http method='GET' out=&fname1 &oauth_bearer %end; ; run; + %if &mdebug=1 %then %do; %put &sysmacroname: fetching log content from &base_uri&logloc/content; data _null_;infile &fname1;input;putlog _infile_;run; %end; + %if &SYS_PROCHTTP_STATUS_CODE=400 %then %do; /* fetch log from parent session */ %let logloc=%substr(&logloc,1,%index(&logloc,%str(/jobs/))-1); @@ -262,9 +264,12 @@ run; data _null_;infile &fname1;input;putlog _infile_;run; %end; %end; + %if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do; - data _null_;infile &fname1;input;putlog _infile_;run; + %if &mdebug ne 1 %then %do; /* have already output above */ + data _null_;infile &fname1;input;putlog _infile_;run; + %end; %mp_abort(mac=&sysmacroname ,msg=%str(logfetch: &SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE) )