%ZTM ;SEA/RDS-TaskMan: Manager, Part 1 (Main Loop) ;10/02/08 09:00
;;8.0;KERNEL;**24,36,64,67,118,127,136,275,355,446**;JUL 10, 1995;Build 44
;Per VHA Directive 2004-038, this routine should not be modified.
;%ZTCHK is set to 1 @ top of SCHQ, set to 0 if sent a task to SM
LOOP ;Taskman's Main Loop
S %ZTRUN=1,%ZTCHK=1
F %ZTLOOP=0:1 S %ZTLOOP=%ZTLOOP#16 D CHECK,SCHQ,IDLE:%ZTCHK
S %ZTFALL="" G LOOP
;
CHECK ;LOOP--Check Status And Update Loop Data
;Do CHECK if sent a new job or %ZTLOOP=0.
Q:%ZTLOOP&$G(%ZTCHK)
I $D(^%ZTSCH("STOP","MGR",%ZTPAIR)) G HALT^%ZTM0
S ^%ZTSCH("RUN")=$H,ZTPAIR="",%ZTIME=$$H3($H)
I $D(^%ZTSCH("WAIT","MGR"))#2 D STATUS("WAIT","Taskman Waiting") H 5 G CHECK
;
I '$D(^%ZTSCH("UPDATE",$J)) D UPDATE^%ZTM5
I %ZTVLI D STATUS("PAUSE","Logons Inhibited") H 60 G CHECK ;Set in %ZTM5
I @%ZTNLG D INHIBIT^%ZTM5(1),STATUS("PAUSE","No Signons Allowed") H 60 G CHECK
I $G(^%ZIS(14.5,"LOGON",%ZTVOL)) D INHIBIT^%ZTM5(0) ;Check field
I $D(ZTREQUIR)#2 D STATUS("PAUSE","Required link to "_ZTREQUIR_" is down.") H 60 D REQUIR^%ZTM5 G CHECK
;
I $D(^%ZTSCH("LINK"))#2,$$DIFF($H,^("LINK"))>900 D LINK^%ZTM3
;Job Limit check done in NEWJOB. p446
;
I $L(%ZTPFLG("BAL")) D I ZTOVERLD G CHECK
. S ZTOVERLD=0
. Q:%ZTPFLG("LBT")>%ZTIME ;Running, Not time to recheck
. S %ZTPFLG("LBT")=%ZTIME+%ZTPFLG("BI") ;Next time to check.
. D BALANCE^%ZTM6 Q:'ZTOVERLD
. D STATUS("BALANCE","Load Balance Wait.")
. ;Start submanagers for C list work
. I $D(^%ZTSCH("C",%ZTPAIR))>9 D NEWJOB(%ZTUCI,%ZTVOL,"")
. N T F T=1:2:%ZTPFLG("BI") H 2 Q:$$STOPWT^%ZTM6() ;p446 Wait, Check if leave early
. Q
;
I %ZTRUN D STATUS("RUN","Main Loop")
I '%ZTRUN D
. D STATUS("RUN","Taskman Job Limit Reached"),CHECK^%ZTM6
. S %ZTPFLG("JLC")=(%ZTPFLG("JLC")+1)#3
. I '%ZTPFLG("JLC") S %ZTRUN=%ZTVMJ>$$ACTJ^%ZOSV ;ReCheck for job limit p446
Q
;
STATUS(ST,MSG) ;Record TM status
N F
;p446 Only update status every 5 seconds, unless MSG has changed.
S F=(MSG'=$G(%ZTPFLG("StatusM")))
I $G(%ZTPFLG("Status"))>%ZTIME,'$G(F) Q
S ^%ZTSCH("STATUS",$J)=$H_"^"_ST_"^"_$G(%ZTPAIR)_"^"_MSG
S %ZTPFLG("Status")=%ZTIME+5,%ZTPFLG("StatusM")=MSG
Q
;
TLOCK(M) ;Lock/unlock the SCHQ node
I M>0 L +^%ZTSCH("SCHQ"):%ZTLKTM Q $T
L -^%ZTSCH("SCHQ") Q
;
SCHQ ;LOOP--Check Schedule List
S %ZTIME=$$H3($H),ZTDTH=0,ZTSK=0,%ZTCHK=1,IO=""
I '$$TLOCK(1) Q ;Lock and Sync %ZTSCH
S1 S ZTDTH=$O(^%ZTSCH(ZTDTH)),ZTSK=0 I (ZTDTH>%ZTIME)!('ZTDTH)!(ZTDTH'?1.N) D TLOCK(-1) Q
I +ZTDTH<0 K ^%ZTSCH(ZTDTH) G S1
S2 S ZTSK=$O(^%ZTSCH(ZTDTH,ZTSK)) I ZTSK="" G S1
S ZTST=$G(^%ZTSCH(ZTDTH,ZTSK))
;Get task lock then release SCHQ lock
L +^%ZTSK(ZTSK):0 G S2:'$T
K ^%ZTSCH(ZTDTH,ZTSK) D TLOCK(-1)
I $D(^%ZTSK(ZTSK,0))[0 D TSKSTAT("I") L -^%ZTSK(ZTSK) Q ;p446
I $L($P($G(^%ZTSK(ZTSK,.1)),U,10)) D TSKSTAT("D","Stopped") L -^%ZTSK(ZTSK) Q ;p446
D ^%ZTM1
I %ZTREJCT L -^%ZTSK(ZTSK) Q ;p446, Need to get SCHQ lock again.
;Count tasks
S %ZTMON(%ZTMON)=$G(%ZTMON(%ZTMON))+1
;
SEND ;Send Task To Submanager
S %ZTCHK=0,ZTPAIR=""
I ZTDVOL'=%ZTVOL D XLINK^%ZTM2 G:'ZTJOBIT SCHX
;Clear before job cmd
L +^%ZTSCH("JOBQ"):99
I (ZTYPE'="C")&(%ZTNODE[ZTNODE) D
. D TSKSTAT(3,"Placed on JOB List")
. S ^%ZTSCH("JOB",ZTDTH,ZTSK)=IO ;No other lock on JOB
E D
. D TSKSTAT("M","Placed on C List")
. S ZTPAIR=ZTDVOL_$S($L(ZTNODE):":"_ZTNODE,1:"")
. S ^%ZTSCH("C",ZTPAIR,ZTDTH,ZTSK)=IO
;
L -^%ZTSK(ZTSK),-^%ZTSCH("JOBQ")
;Check if need new sub-manager.
I (ZTYPE="C")!$$NEWSUB,'$$OOS(ZTPAIR) D NEWJOB(ZTUCI,ZTDVOL,ZTNODE)
SCHX ;Clear all locks
L K ZTREP
Q
;
IDLE ;LOOP--DEV Node Maintenance; Backup JOB Commands
N R,C,T
I %ZTMON("NEXT")'>%ZTIME D MON ;See if time to update %ZTMON
S (ZTREC,ZTCVOL)="" H 1 ;This is the main hang
I $D(^%ZTSCH("STOP","MGR",%ZTPAIR)) Q
;job off a new submanager if MIN count < # SUBs
I $$NEWSUB D NEWJOB(%ZTUCI,%ZTVOL,"")
;Job off a new submanagers if the JOB list is long.
S R=$NA(^%ZTSCH("JOB")),C=0,T=15
F S R=$Q(@R),C=C+1 Q:R'["JOB" I C>T D NEWJOB(%ZTUCI,%ZTVOL,"") Q ;Just start one at a time ;p446
;Other Idle work.
L +^%ZTSCH("IDLE",%ZTPAIR):%ZTLKTM Q:'$T D IDLE1 L -^%ZTSCH("IDLE",%ZTPAIR)
Q
;
IDLE1 ;only proceed with idle work if 60 seconds since last check
I $$DIFF(%ZTIME,^%ZTSCH("IDLE"),1)<60 Q
S ^%ZTSCH("IDLE")=%ZTIME ;Set new time.
I %ZTPFLG("XUSCNT") D TOUCH^XUSCNT
D I1,I2 X "JOB DETACH^%ZTM"
Q
;
I1 ;clear out old DEV nodes
N X,%ZTIO S %ZTIO=""
F S %ZTIO=$O(^%ZTSCH("DEV",%ZTIO)) Q:%ZTIO="" L +^%ZTSCH("DEV",%ZTIO):0 I $T D L -^%ZTSCH("DEV",%ZTIO)
. S X=$G(^%ZTSCH("DEV",%ZTIO)) Q:'$L(X)
. I $$DIFF(%ZTIME,X,1)>120 K ^%ZTSCH("DEV",%ZTIO)
. Q
Q
;
I2 ;job new submanagers cross-volume for each unfinished C list
I $D(^%ZTSCH("C")) D
. N Y,ZTUCI,ZTVOL,ZTNODE,$ETRAP,$ESTACK S $ET="S $EC="""" D ERCL^%ZTM2"
. S ZTVOL="" F S ZTVOL=$O(^%ZTSCH("C",ZTVOL)) Q:ZTVOL="" D
.. I $O(^%ZTSCH("C",ZTVOL,0))="" Q
.. S ZTNODE="",ZTDVOL=ZTVOL S:ZTDVOL[":" ZTNODE=$P(ZTDVOL,":",2),ZTDVOL=$P(ZTDVOL,":")
.. S X=$G(^%ZTSCH("C",ZTVOL))
.. I $D(^%ZTSCH("LINK",ZTDVOL))!(X>9)!$$OOS(ZTVOL) Q
.. S ^%ZTSCH("C",ZTVOL)=X+1
.. S ZTUCI=$O(^%ZIS(14.6,"AV",ZTDVOL,""))
.. D NEWJOB(ZTUCI,ZTDVOL,ZTNODE)
.. Q
. Q
Q
;
MON ;Set Next %ZTMON each Hour
I %ZTMON("DAY")<+$H D DAY^%ZTM5
S %ZTMON=$P($H,",",2)\3600,%ZTMON(%ZTMON)=0
S %ZTMON("NEXT")=($H*86400)+(%ZTMON+1*3600)
D HOUR^%ZTM5
Q
;
NEWJOB(ZTUCI,ZTDVOL,ZTNODE) ;Start a new Job
S %ZTRUN=%ZTVMJ>$$ACTJ^%ZOSV ;Check for job limit p446
;At the job limit if $ZTRUN=0
I '%ZTRUN D STATUS("RUN","Taskman Job Limit Reached") Q
S ZTUCI=$G(ZTUCI),ZTDVOL=$G(ZTDVOL),ZTNODE=$G(ZTNODE)
X %ZTJOB H %ZTSLO ;If job doesn't work, will catch next time.
Q
;
DIFF(N,O,T) ;Diff in sec.
Q:$G(T) N-O ;For new seconds times
Q N-O*86400-$P(O,",",2)+$P(N,",",2)
;
OOS(BV) ;Check if Box-Volume is Out Of Service, Return 1 if OOS.
Q:BV="" 0 N %
S %=$O(^%ZIS(14.7,"B",BV,0)),%=$G(^%ZIS(14.7,+%,0))
Q:%="" 1 Q $P(%,U,11)=1
;
H3(%) ;Convert $H to seconds.
Q 86400*%+$P(%,",",2)
;
H0(%) ;Covert from seconds to $H
Q (%\86400)_","_(%#86400)
;
SUBOK() ;Check if sub's are starting, return 1 if OK
N T L +^%ZTSCH("SUB",%ZTPAIR):0 S T=$T
S ^%ZTSCH("SUB",%ZTPAIR,0)=($G(^%ZTSCH("SUB",%ZTPAIR,0))+1)_"^"_$H
I T L -^%ZTSCH("SUB",%ZTPAIR)
Q ^%ZTSCH("SUB",%ZTPAIR,0)<10
;
NEWSUB() ;See if we need a new submanager
N SUBS,T
L +^%ZTSCH("SUB",%ZTPAIR):0 S T=$T ;Sync ^%ZTSCH("SUB",%ZTPAIR)
S SUBS=^%ZTSCH("SUB",%ZTPAIR)
I T L -^%ZTSCH("SUB",%ZTPAIR)
Q SUBS<%ZTPFLG("MINSUB")
;
TSKSTAT(CODE,MSG) ; Update task's status
S $P(^%ZTSK(ZTSK,.1),U,1,4)=$G(CODE)_U_$H_U_$G(MSG)_U_$J
Q
;
DETACH ;Do slow work in background job
D PARAMS^%ZTM5 S $ET="D ^%ZTER"
D I5,I6
Q
;
I5 ;Clean up %ZTSCH
S ZTDTH="0,0" F S ZTDTH=$O(^%ZTSCH(ZTDTH)) Q:ZTDTH'["," D
. L +^%ZTSCH("SCHQ"):%ZTLKTM Q:'$T ;Keep others out while cleaning
. N ZTSK,X
. S ZTSK=$O(^%ZTSCH(ZTDTH,0)) I ZTSK>0 S X=^(ZTSK),^%ZTSCH($$H3(ZTDTH),ZTSK)=X K ^%ZTSCH(ZTDTH,ZTSK)
. L -^%ZTSCH("SCHQ")
. Q
Q
;
I6 ;Check on persistent jobs, Locks can take time, Called from %ZTM0 at start.
S ZTSK=0 F S ZTSK=$O(^%ZTSCH("TASK",ZTSK)) Q:ZTSK'>0 D:$D(^%ZTSCH("TASK",ZTSK,"P"))
. L +^%ZTSCH("TASK",ZTSK):%ZTLKTM E Q ;Still running
. D:$D(^%ZTSCH("TASK",ZTSK,"P")) REQP^%ZTLOAD3(ZTSK) ;START NEW TASK.
. K ^%ZTSCH("TASK",ZTSK)
. L -^%ZTSCH("TASK",ZTSK)
. Q
K %ZTVS
Q
;
%ZTM ;SEA/RDS-TaskMan: Manager, Part 1 (Main Loop) ;10/02/08 09:00
+1 ;;8.0;KERNEL;**24,36,64,67,118,127,136,275,355,446**;JUL 10, 1995;Build 44
+2 ;Per VHA Directive 2004-038, this routine should not be modified.
+3 ;%ZTCHK is set to 1 @ top of SCHQ, set to 0 if sent a task to SM
LOOP ;Taskman's Main Loop
+1 SET %ZTRUN=1
SET %ZTCHK=1
+2 FOR %ZTLOOP=0:1
SET %ZTLOOP=%ZTLOOP#16
DO CHECK
DO SCHQ
IF %ZTCHK
DO IDLE
+3 SET %ZTFALL=""
GOTO LOOP
+4 ;
CHECK ;LOOP--Check Status And Update Loop Data
+1 ;Do CHECK if sent a new job or %ZTLOOP=0.
+2 IF %ZTLOOP&$GET(%ZTCHK)
QUIT
+3 IF $DATA(^%ZTSCH("STOP","MGR",%ZTPAIR))
GOTO HALT^%ZTM0
+4 SET ^%ZTSCH("RUN")=$HOROLOG
SET ZTPAIR=""
SET %ZTIME=$$H3($HOROLOG)
+5 IF $DATA(^%ZTSCH("WAIT","MGR"))#2
DO STATUS("WAIT","Taskman Waiting")
HANG 5
GOTO CHECK
+6 ;
+7 IF '$DATA(^%ZTSCH("UPDATE",$JOB))
DO UPDATE^%ZTM5
+8 ;Set in %ZTM5
IF %ZTVLI
DO STATUS("PAUSE","Logons Inhibited")
HANG 60
GOTO CHECK
+9 IF @%ZTNLG
DO INHIBIT^%ZTM5(1)
DO STATUS("PAUSE","No Signons Allowed")
HANG 60
GOTO CHECK
+10 ;Check field
IF $GET(^%ZIS(14.5,"LOGON",%ZTVOL))
DO INHIBIT^%ZTM5(0)
+11 IF $DATA(ZTREQUIR)#2
DO STATUS("PAUSE","Required link to "_ZTREQUIR_" is down.")
HANG 60
DO REQUIR^%ZTM5
GOTO CHECK
+12 ;
+13 IF $DATA(^%ZTSCH("LINK"))#2
IF $$DIFF($HOROLOG,^("LINK"))>900
DO LINK^%ZTM3
+14 ;Job Limit check done in NEWJOB. p446
+15 ;
+16 IF $LENGTH(%ZTPFLG("BAL"))
Begin DoDot:1
+17 SET ZTOVERLD=0
+18 ;Running, Not time to recheck
IF %ZTPFLG("LBT")>%ZTIME
QUIT
+19 ;Next time to check.
SET %ZTPFLG("LBT")=%ZTIME+%ZTPFLG("BI")
+20 DO BALANCE^%ZTM6
IF 'ZTOVERLD
QUIT
+21 DO STATUS("BALANCE","Load Balance Wait.")
+22 ;Start submanagers for C list work
+23 IF $DATA(^%ZTSCH("C",%ZTPAIR))>9
DO NEWJOB(%ZTUCI,%ZTVOL,"")
+24 ;p446 Wait, Check if leave early
NEW T
FOR T=1:2:%ZTPFLG("BI")
HANG 2
IF $$STOPWT^%ZTM6()
QUIT
+25 QUIT
End DoDot:1
IF ZTOVERLD
GOTO CHECK
+26 ;
+27 IF %ZTRUN
DO STATUS("RUN","Main Loop")
+28 IF '%ZTRUN
Begin DoDot:1
+29 DO STATUS("RUN","Taskman Job Limit Reached")
DO CHECK^%ZTM6
+30 SET %ZTPFLG("JLC")=(%ZTPFLG("JLC")+1)#3
+31 ;ReCheck for job limit p446
IF '%ZTPFLG("JLC")
SET %ZTRUN=%ZTVMJ>$$ACTJ^%ZOSV
End DoDot:1
+32 QUIT
+33 ;
STATUS(ST,MSG) ;Record TM status
+1 NEW F
+2 ;p446 Only update status every 5 seconds, unless MSG has changed.
+3 SET F=(MSG'=$GET(%ZTPFLG("StatusM")))
+4 IF $GET(%ZTPFLG("Status"))>%ZTIME
IF '$GET(F)
QUIT
+5 SET ^%ZTSCH("STATUS",$JOB)=$HOROLOG_"^"_ST_"^"_$GET(%ZTPAIR)_"^"_MSG
+6 SET %ZTPFLG("Status")=%ZTIME+5
SET %ZTPFLG("StatusM")=MSG
+7 QUIT
+8 ;
TLOCK(M) ;Lock/unlock the SCHQ node
+1 IF M>0
LOCK +^%ZTSCH("SCHQ"):%ZTLKTM
QUIT $TEST
+2 LOCK -^%ZTSCH("SCHQ")
QUIT
+3 ;
SCHQ ;LOOP--Check Schedule List
+1 SET %ZTIME=$$H3($HOROLOG)
SET ZTDTH=0
SET ZTSK=0
SET %ZTCHK=1
SET IO=""
+2 ;Lock and Sync %ZTSCH
IF '$$TLOCK(1)
QUIT
S1 SET ZTDTH=$ORDER(^%ZTSCH(ZTDTH))
SET ZTSK=0
IF (ZTDTH>%ZTIME)!('ZTDTH)!(ZTDTH'?1.N)
DO TLOCK(-1)
QUIT
+1 IF +ZTDTH<0
KILL ^%ZTSCH(ZTDTH)
GOTO S1
S2 SET ZTSK=$ORDER(^%ZTSCH(ZTDTH,ZTSK))
IF ZTSK=""
GOTO S1
+1 SET ZTST=$GET(^%ZTSCH(ZTDTH,ZTSK))
+2 ;Get task lock then release SCHQ lock
+3 LOCK +^%ZTSK(ZTSK):0
IF '$TEST
GOTO S2
+4 KILL ^%ZTSCH(ZTDTH,ZTSK)
DO TLOCK(-1)
+5 ;p446
IF $DATA(^%ZTSK(ZTSK,0))[0
DO TSKSTAT("I")
LOCK -^%ZTSK(ZTSK)
QUIT
+6 ;p446
IF $LENGTH($PIECE($GET(^%ZTSK(ZTSK,.1)),U,10))
DO TSKSTAT("D","Stopped")
LOCK -^%ZTSK(ZTSK)
QUIT
+7 DO ^%ZTM1
+8 ;p446, Need to get SCHQ lock again.
IF %ZTREJCT
LOCK -^%ZTSK(ZTSK)
QUIT
+9 ;Count tasks
+10 SET %ZTMON(%ZTMON)=$GET(%ZTMON(%ZTMON))+1
+11 ;
SEND ;Send Task To Submanager
+1 SET %ZTCHK=0
SET ZTPAIR=""
+2 IF ZTDVOL'=%ZTVOL
DO XLINK^%ZTM2
IF 'ZTJOBIT
GOTO SCHX
+3 ;Clear before job cmd
+4 LOCK +^%ZTSCH("JOBQ"):99
+5 IF (ZTYPE'="C")&(%ZTNODE[ZTNODE)
Begin DoDot:1
+6 DO TSKSTAT(3,"Placed on JOB List")
+7 ;No other lock on JOB
SET ^%ZTSCH("JOB",ZTDTH,ZTSK)=IO
End DoDot:1
+8 IF '$TEST
Begin DoDot:1
+9 DO TSKSTAT("M","Placed on C List")
+10 SET ZTPAIR=ZTDVOL_$SELECT($LENGTH(ZTNODE):":"_ZTNODE,1:"")
+11 SET ^%ZTSCH("C",ZTPAIR,ZTDTH,ZTSK)=IO
End DoDot:1
+12 ;
+13 LOCK -^%ZTSK(ZTSK),-^%ZTSCH("JOBQ")
+14 ;Check if need new sub-manager.
+15 IF (ZTYPE="C")!$$NEWSUB
IF '$$OOS(ZTPAIR)
DO NEWJOB(ZTUCI,ZTDVOL,ZTNODE)
SCHX ;Clear all locks
+1 LOCK
KILL ZTREP
+2 QUIT
+3 ;
IDLE ;LOOP--DEV Node Maintenance; Backup JOB Commands
+1 NEW R,C,T
+2 ;See if time to update %ZTMON
IF %ZTMON("NEXT")'>%ZTIME
DO MON
+3 ;This is the main hang
SET (ZTREC,ZTCVOL)=""
HANG 1
+4 IF $DATA(^%ZTSCH("STOP","MGR",%ZTPAIR))
QUIT
+5 ;job off a new submanager if MIN count < # SUBs
+6 IF $$NEWSUB
DO NEWJOB(%ZTUCI,%ZTVOL,"")
+7 ;Job off a new submanagers if the JOB list is long.
+8 SET R=$NAME(^%ZTSCH("JOB"))
SET C=0
SET T=15
+9 ;Just start one at a time ;p446
FOR
SET R=$QUERY(@R)
SET C=C+1
IF R'["JOB"
QUIT
IF C>T
DO NEWJOB(%ZTUCI,%ZTVOL,"")
QUIT
+10 ;Other Idle work.
+11 LOCK +^%ZTSCH("IDLE",%ZTPAIR):%ZTLKTM
IF '$TEST
QUIT
DO IDLE1
LOCK -^%ZTSCH("IDLE",%ZTPAIR)
+12 QUIT
+13 ;
IDLE1 ;only proceed with idle work if 60 seconds since last check
+1 IF $$DIFF(%ZTIME,^%ZTSCH("IDLE"),1)<60
QUIT
+2 ;Set new time.
SET ^%ZTSCH("IDLE")=%ZTIME
+3 IF %ZTPFLG("XUSCNT")
DO TOUCH^XUSCNT
+4 DO I1
DO I2
XECUTE "JOB DETACH^%ZTM"
+5 QUIT
+6 ;
I1 ;clear out old DEV nodes
+1 NEW X,%ZTIO
SET %ZTIO=""
+2 FOR
SET %ZTIO=$ORDER(^%ZTSCH("DEV",%ZTIO))
IF %ZTIO=""
QUIT
LOCK +^%ZTSCH("DEV",%ZTIO):0
IF $TEST
Begin DoDot:1
+3 SET X=$GET(^%ZTSCH("DEV",%ZTIO))
IF '$LENGTH(X)
QUIT
+4 IF $$DIFF(%ZTIME,X,1)>120
KILL ^%ZTSCH("DEV",%ZTIO)
+5 QUIT
End DoDot:1
LOCK -^%ZTSCH("DEV",%ZTIO)
+6 QUIT
+7 ;
I2 ;job new submanagers cross-volume for each unfinished C list
+1 IF $DATA(^%ZTSCH("C"))
Begin DoDot:1
+2 NEW Y,ZTUCI,ZTVOL,ZTNODE,$ETRAP,$ESTACK
SET $ETRAP="S $EC="""" D ERCL^%ZTM2"
+3 SET ZTVOL=""
FOR
SET ZTVOL=$ORDER(^%ZTSCH("C",ZTVOL))
IF ZTVOL=""
QUIT
Begin DoDot:2
+4 IF $ORDER(^%ZTSCH("C",ZTVOL,0))=""
QUIT
+5 SET ZTNODE=""
SET ZTDVOL=ZTVOL
IF ZTDVOL["
SET ZTNODE=$PIECE(ZTDVOL,":",2)
SET ZTDVOL=$PIECE(ZTDVOL,":")
+6 SET X=$GET(^%ZTSCH("C",ZTVOL))
+7 IF $DATA(^%ZTSCH("LINK",ZTDVOL))!(X>9)!$$OOS(ZTVOL)
QUIT
+8 SET ^%ZTSCH("C",ZTVOL)=X+1
+9 SET ZTUCI=$ORDER(^%ZIS(14.6,"AV",ZTDVOL,""))
+10 DO NEWJOB(ZTUCI,ZTDVOL,ZTNODE)
+11 QUIT
End DoDot:2
+12 QUIT
End DoDot:1
+13 QUIT
+14 ;
MON ;Set Next %ZTMON each Hour
+1 IF %ZTMON("DAY")<+$HOROLOG
DO DAY^%ZTM5
+2 SET %ZTMON=$PIECE($HOROLOG,",",2)\3600
SET %ZTMON(%ZTMON)=0
+3 SET %ZTMON("NEXT")=($HOROLOG*86400)+(%ZTMON+1*3600)
+4 DO HOUR^%ZTM5
+5 QUIT
+6 ;
NEWJOB(ZTUCI,ZTDVOL,ZTNODE) ;Start a new Job
+1 ;Check for job limit p446
SET %ZTRUN=%ZTVMJ>$$ACTJ^%ZOSV
+2 ;At the job limit if $ZTRUN=0
+3 IF '%ZTRUN
DO STATUS("RUN","Taskman Job Limit Reached")
QUIT
+4 SET ZTUCI=$GET(ZTUCI)
SET ZTDVOL=$GET(ZTDVOL)
SET ZTNODE=$GET(ZTNODE)
+5 ;If job doesn't work, will catch next time.
XECUTE %ZTJOB
HANG %ZTSLO
+6 QUIT
+7 ;
DIFF(N,O,T) ;Diff in sec.
+1 ;For new seconds times
IF $GET(T)
QUIT N-O
+2 QUIT N-O*86400-$PIECE(O,",",2)+$PIECE(N,",",2)
+3 ;
OOS(BV) ;Check if Box-Volume is Out Of Service, Return 1 if OOS.
+1 IF BV=""
QUIT 0
NEW %
+2 SET %=$ORDER(^%ZIS(14.7,"B",BV,0))
SET %=$GET(^%ZIS(14.7,+%,0))
+3 IF %=""
QUIT 1
QUIT $PIECE(%,U,11)=1
+4 ;
H3(%) ;Convert $H to seconds.
+1 QUIT 86400*%+$PIECE(%,",",2)
+2 ;
H0(%) ;Covert from seconds to $H
+1 QUIT (%\86400)_","_(%#86400)
+2 ;
SUBOK() ;Check if sub's are starting, return 1 if OK
+1 NEW T
LOCK +^%ZTSCH("SUB",%ZTPAIR):0
SET T=$TEST
+2 SET ^%ZTSCH("SUB",%ZTPAIR,0)=($GET(^%ZTSCH("SUB",%ZTPAIR,0))+1)_"^"_$HOROLOG
+3 IF T
LOCK -^%ZTSCH("SUB",%ZTPAIR)
+4 QUIT ^%ZTSCH("SUB",%ZTPAIR,0)<10
+5 ;
NEWSUB() ;See if we need a new submanager
+1 NEW SUBS,T
+2 ;Sync ^%ZTSCH("SUB",%ZTPAIR)
LOCK +^%ZTSCH("SUB",%ZTPAIR):0
SET T=$TEST
+3 SET SUBS=^%ZTSCH("SUB",%ZTPAIR)
+4 IF T
LOCK -^%ZTSCH("SUB",%ZTPAIR)
+5 QUIT SUBS<%ZTPFLG("MINSUB")
+6 ;
TSKSTAT(CODE,MSG) ; Update task's status
+1 SET $PIECE(^%ZTSK(ZTSK,.1),U,1,4)=$GET(CODE)_U_$HOROLOG_U_$GET(MSG)_U_$JOB
+2 QUIT
+3 ;
DETACH ;Do slow work in background job
+1 DO PARAMS^%ZTM5
SET $ETRAP="D ^%ZTER"
+2 DO I5
DO I6
+3 QUIT
+4 ;
I5 ;Clean up %ZTSCH
+1 SET ZTDTH="0,0"
FOR
SET ZTDTH=$ORDER(^%ZTSCH(ZTDTH))
IF ZTDTH'[","
QUIT
Begin DoDot:1
+2 ;Keep others out while cleaning
LOCK +^%ZTSCH("SCHQ"):%ZTLKTM
IF '$TEST
QUIT
+3 NEW ZTSK,X
+4 SET ZTSK=$ORDER(^%ZTSCH(ZTDTH,0))
IF ZTSK>0
SET X=^(ZTSK)
SET ^%ZTSCH($$H3(ZTDTH),ZTSK)=X
KILL ^%ZTSCH(ZTDTH,ZTSK)
+5 LOCK -^%ZTSCH("SCHQ")
+6 QUIT
End DoDot:1
+7 QUIT
+8 ;
I6 ;Check on persistent jobs, Locks can take time, Called from %ZTM0 at start.
+1 SET ZTSK=0
FOR
SET ZTSK=$ORDER(^%ZTSCH("TASK",ZTSK))
IF ZTSK'>0
QUIT
IF $DATA(^%ZTSCH("TASK",ZTSK,"P"))
Begin DoDot:1
+2 ;Still running
LOCK +^%ZTSCH("TASK",ZTSK):%ZTLKTM
IF '$TEST
QUIT
+3 ;START NEW TASK.
IF $DATA(^%ZTSCH("TASK",ZTSK,"P"))
DO REQP^%ZTLOAD3(ZTSK)
+4 KILL ^%ZTSCH("TASK",ZTSK)
+5 LOCK -^%ZTSCH("TASK",ZTSK)
+6 QUIT
End DoDot:1
+7 KILL %ZTVS
+8 QUIT
+9 ;