HLOFILER ;ALB/CJM- Passes messages on the incoming queue to the applications - 10/4/94 1pm ;03/12/2012
;;1.6;HEALTH LEVEL SEVEN;**126,131,134,137,152,158**;Oct 13, 1995;Build 14
;Per VHA Directive 2004-038, this routine should not be modified.
;
;GET WORK function for the process running under the Process Manager
GETWORK(QUE) ;
;Input:
; QUE - (pass by reference) These subscripts are used:
; ("FROM") - sending facility last obtained
; ("QUEUE") - name of the queue last obtained
;Output:
; Function returns 1 if success, 0 if no more work
; QUE- updated to identify next queu of messages to process.
;
N FROM,QUEUE
S FROM=$G(QUE("FROM")),QUEUE=$G(QUE("QUEUE"))
I ($G(FROM)]""),($G(QUEUE)]"") D
.L -^HLB("QUEUE","IN",FROM,QUEUE)
.F S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="") I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
I ($G(FROM)]""),($G(QUEUE)="") D
.F S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM="" D Q:($G(QUEUE)]"")
..S QUEUE="" F S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="") I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
I FROM="" D
.F S FROM=$O(^HLB("QUEUE","IN",FROM)) Q:FROM="" D Q:($G(QUEUE)]"")
..S QUEUE="" F S QUEUE=$O(^HLB("QUEUE","IN",FROM,QUEUE)) Q:(QUEUE="") I '$$STOPPED^HLOQUE("IN",QUEUE) L +^HLB("QUEUE","IN",FROM,QUEUE):0 Q:$T
S QUE("FROM")=FROM,QUE("QUEUE")=QUEUE
Q:(QUEUE]"") 1
Q 0
;
DOWORK(QUEUE) ;passes the messages on the queue to the application
N $ETRAP,$ESTACK S $ETRAP="G ERROR^HLOFILER"
;
N MSGIEN,DEQUE,QUE,COUNT
M QUE=QUEUE
S (DEQUE,COUNT)=0
S MSGIEN=0
;
F S MSGIEN=$O(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN)) Q:'MSGIEN S COUNT=COUNT+1 Q:COUNT>1000 D M QUEUE=QUE
.N MCODE,ACTION,QUE,PURGE,ORIG,NODE,COUNT
.N $ETRAP,$ESTACK S $ETRAP="G ERROR2^HLOFILER"
.S NODE=$G(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN))
.S ACTION=$P(NODE,"^",1,2)
.S PURGE=$P(NODE,"^",3)
.S ORIG("IEN")=$P(NODE,"^",4),ORIG("ACK BY")=$P(NODE,"^",5),ORIG("STATUS")=$P(NODE,"^",6)
.D DEQUE(MSGIEN,PURGE,.ORIG)
.I ACTION]"" D
..N HLMSGIEN,MCODE,DEQUE,DUZ
..N $ETRAP,$ESTACK S $ETRAP="G ERROR3^HLOFILER"
..S HLMSGIEN=MSGIEN
..S MCODE="D "_ACTION
..N MSGIEN,X
..D DUZ^XUP(.5)
..X MCODE
..;kill the apps variables
..D
...N ZTSK
...D KILL^XUSCLEAN
;
ENDWORK ;where the execution resumes upon an error
D DEQUE()
Q
;
DEQUE(MSGIEN,PURGE,ORIG) ;
;Dequeues the message. Also sets up the purge indicator and the completion status.
S:$G(MSGIEN) DEQUE=$G(DEQUE)+1,DEQUE(MSGIEN)=PURGE_"^"_ORIG("IEN")_"^"_ORIG("ACK BY")_"^"_ORIG("STATUS")
I '$G(MSGIEN)!($G(DEQUE)>25) S MSGIEN=0 D
.F S MSGIEN=$O(DEQUE(MSGIEN)) Q:'MSGIEN D
..N NODE,PURGE,ORIG
..S NODE=DEQUE(MSGIEN)
..S PURGE=$P(NODE,"^"),ORIG("IEN")=$P(NODE,"^",2),ORIG("ACK BY")=$P(NODE,"^",3),ORIG("STATUS")=$P(NODE,"^",4)
..D DEQUE^HLOQUE(QUEUE("FROM"),QUEUE("QUEUE"),"IN",MSGIEN)
..S $P(^HLB(MSGIEN,0),"^",19)=1 ;sets the flag to show that the app handoff was done
..;
..;update original message
..I ORIG("IEN"),$D(^HLB(ORIG("IEN"),0)) D
...S:$L(ORIG("ACK BY")) $P(^HLB(ORIG("IEN"),0),"^",7)=ORIG("ACK BY"),$P(^HLB(ORIG("IEN"),0),"^",18)=1
...S:$L(ORIG("STATUS")) $P(^HLB(ORIG("IEN"),0),"^",20)=ORIG("STATUS")
..;
ZB2 ..D:PURGE
...N STATUS
...S STATUS=$P(^HLB(MSGIEN,0),"^",20)
...S:STATUS="" $P(^HLB(MSGIEN,0),"^",20)="SU",STATUS="SU"
...D SETPURGE^HLOF778A(MSGIEN,STATUS,ORIG("IEN"),ORIG("STATUS"))
.K DEQUE S DEQUE=0
Q
;
ERROR ;error trap
S $ETRAP="Q:$QUIT """" Q"
N HOUR
S HOUR=$E($$NOW^XLFDT,1,10)
S ^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2))=$G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))+1
;
D DEQUE()
;
;a lot of errors of the same type may indicate an endless loop
;return to the Process Manager error trap
I ($G(^TMP("HL7 ERRORS",$J,HOUR,$P($ECODE,",",2)))>30) Q:$QUIT "" Q
;
;while debugging quit on all errors - returns to the Process Manager error trap
I $G(^HLTMP("LOG ALL ERRORS")) Q:$QUIT "" Q
I $ECODE["EDITED" Q:$QUIT "" Q
;
D ^%ZTER
D UNWIND^%ZTER
Q:$QUIT ""
Q
;
ERROR2 ;
S $ETRAP="Q:$QUIT """" Q"
;
D DEQUE()
;
;may need to change the status to Error
D
.N NODE,RAPP,SAPP,FS,CS,REP,ESCAPE,SUBCOMP,HDR,DIR,NOW,SYS
.D SYSPARMS^HLOSITE(.SYS)
.S NOW=$$NOW^XLFDT
.S NODE=$G(^HLB(MSGIEN,0))
.Q:NODE=""
.Q:$P(NODE,"^",20)="ER"
.S $P(NODE,"^",20)="ER",$P(NODE,"^",21)="APPLICATION ROUTINE ERROR"
.S DIR=$S($E($P(NODE,"^",4))="I":"IN",1:"OUT")
.I $P(NODE,"^",9) K ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)
.S $P(NODE,"^",9)=$$FMADD^XLFDT(NOW,SYS("ERROR PURGE"))
.S ^HLB(MSGIEN,0)=NODE
.S ^HLB("AD",DIR,$P(NODE,"^",9),MSGIEN)=""
.S HDR=$G(^HLB(MSGIEN,1))
.S FS=$E(HDR,4)
.Q:FS=""
.S CS=$E(HDR,5)
.S REP=$E(HDR,6)
.S ESCAPE=$E(HDR,7)
.S SUBCOMP=$E(HDR,8)
.S RAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
.I RAPP="" S RAPP="UNKNOWN"
.S SAPP=$$DESCAPE^HLOPRS1($P($P(HDR,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
.S ^HLB("ERRORS",RAPP,NOW,MSGIEN)=""
.D COUNT^HLOESTAT(DIR,RAPP,SAPP,"UNKNOWN")
;
;kill the apps variables
D
.N ZTSK,MSGIEN,QUEUE
.D KILL^XUSCLEAN
;
;release all the locks the app may have set, except Taskman lock
L:$D(ZTSK) ^%ZTSCH("TASK",ZTSK):1
L:'$D(ZTSK)
;reset HLO's lock
L +^HLTMP("HL7 RUNNING PROCESSES",$J):0
;return to processing the next message on the queue
S $ECODE=""
;
Q:$QUIT ""
Q
ERROR3 ;error trap for application context
S $ETRAP="Q:$QUIT """" Q"
D ^%ZTER
S $ECODE=",UAPPLICATION ERROR,"
;
;drop to the ERROR2 error handler
Q:$QUIT ""
Q
;
;
;
;
;
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HHLOFILER 5699 printed Nov 22, 2024@17:08:52 Page 2
HLOFILER ;ALB/CJM- Passes messages on the incoming queue to the applications - 10/4/94 1pm ;03/12/2012
+1 ;;1.6;HEALTH LEVEL SEVEN;**126,131,134,137,152,158**;Oct 13, 1995;Build 14
+2 ;Per VHA Directive 2004-038, this routine should not be modified.
+3 ;
+4 ;GET WORK function for the process running under the Process Manager
GETWORK(QUE) ;
+1 ;Input:
+2 ; QUE - (pass by reference) These subscripts are used:
+3 ; ("FROM") - sending facility last obtained
+4 ; ("QUEUE") - name of the queue last obtained
+5 ;Output:
+6 ; Function returns 1 if success, 0 if no more work
+7 ; QUE- updated to identify next queu of messages to process.
+8 ;
+9 NEW FROM,QUEUE
+10 SET FROM=$GET(QUE("FROM"))
SET QUEUE=$GET(QUE("QUEUE"))
+11 IF ($GET(FROM)]"")
IF ($GET(QUEUE)]"")
Begin DoDot:1
+12 LOCK -^HLB("QUEUE","IN",FROM,QUEUE)
+13 FOR
SET QUEUE=$ORDER(^HLB("QUEUE","IN",FROM,QUEUE))
if (QUEUE="")
QUIT
IF '$$STOPPED^HLOQUE("IN",QUEUE)
LOCK +^HLB("QUEUE","IN",FROM,QUEUE):0
if $TEST
QUIT
End DoDot:1
+14 IF ($GET(FROM)]"")
IF ($GET(QUEUE)="")
Begin DoDot:1
+15 FOR
SET FROM=$ORDER(^HLB("QUEUE","IN",FROM))
if FROM=""
QUIT
Begin DoDot:2
+16 SET QUEUE=""
FOR
SET QUEUE=$ORDER(^HLB("QUEUE","IN",FROM,QUEUE))
if (QUEUE="")
QUIT
IF '$$STOPPED^HLOQUE("IN",QUEUE)
LOCK +^HLB("QUEUE","IN",FROM,QUEUE):0
if $TEST
QUIT
End DoDot:2
if ($GET(QUEUE)]"")
QUIT
End DoDot:1
+17 IF FROM=""
Begin DoDot:1
+18 FOR
SET FROM=$ORDER(^HLB("QUEUE","IN",FROM))
if FROM=""
QUIT
Begin DoDot:2
+19 SET QUEUE=""
FOR
SET QUEUE=$ORDER(^HLB("QUEUE","IN",FROM,QUEUE))
if (QUEUE="")
QUIT
IF '$$STOPPED^HLOQUE("IN",QUEUE)
LOCK +^HLB("QUEUE","IN",FROM,QUEUE):0
if $TEST
QUIT
End DoDot:2
if ($GET(QUEUE)]"")
QUIT
End DoDot:1
+20 SET QUE("FROM")=FROM
SET QUE("QUEUE")=QUEUE
+21 if (QUEUE]"")
QUIT 1
+22 QUIT 0
+23 ;
DOWORK(QUEUE) ;passes the messages on the queue to the application
+1 NEW $ETRAP,$ESTACK
SET $ETRAP="G ERROR^HLOFILER"
+2 ;
+3 NEW MSGIEN,DEQUE,QUE,COUNT
+4 MERGE QUE=QUEUE
+5 SET (DEQUE,COUNT)=0
+6 SET MSGIEN=0
+7 ;
+8 FOR
SET MSGIEN=$ORDER(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN))
if 'MSGIEN
QUIT
SET COUNT=COUNT+1
if COUNT>1000
QUIT
Begin DoDot:1
+9 NEW MCODE,ACTION,QUE,PURGE,ORIG,NODE,COUNT
+10 NEW $ETRAP,$ESTACK
SET $ETRAP="G ERROR2^HLOFILER"
+11 SET NODE=$GET(^HLB("QUEUE","IN",QUEUE("FROM"),QUEUE("QUEUE"),MSGIEN))
+12 SET ACTION=$PIECE(NODE,"^",1,2)
+13 SET PURGE=$PIECE(NODE,"^",3)
+14 SET ORIG("IEN")=$PIECE(NODE,"^",4)
SET ORIG("ACK BY")=$PIECE(NODE,"^",5)
SET ORIG("STATUS")=$PIECE(NODE,"^",6)
+15 DO DEQUE(MSGIEN,PURGE,.ORIG)
+16 IF ACTION]""
Begin DoDot:2
+17 NEW HLMSGIEN,MCODE,DEQUE,DUZ
+18 NEW $ETRAP,$ESTACK
SET $ETRAP="G ERROR3^HLOFILER"
+19 SET HLMSGIEN=MSGIEN
+20 SET MCODE="D "_ACTION
+21 NEW MSGIEN,X
+22 DO DUZ^XUP(.5)
+23 XECUTE MCODE
+24 ;kill the apps variables
+25 Begin DoDot:3
+26 NEW ZTSK
+27 DO KILL^XUSCLEAN
End DoDot:3
End DoDot:2
End DoDot:1
MERGE QUEUE=QUE
+28 ;
ENDWORK ;where the execution resumes upon an error
+1 DO DEQUE()
+2 QUIT
+3 ;
DEQUE(MSGIEN,PURGE,ORIG) ;
+1 ;Dequeues the message. Also sets up the purge indicator and the completion status.
+2 if $GET(MSGIEN)
SET DEQUE=$GET(DEQUE)+1
SET DEQUE(MSGIEN)=PURGE_"^"_ORIG("IEN")_"^"_ORIG("ACK BY")_"^"_ORIG("STATUS")
+3 IF '$GET(MSGIEN)!($GET(DEQUE)>25)
SET MSGIEN=0
Begin DoDot:1
+4 FOR
SET MSGIEN=$ORDER(DEQUE(MSGIEN))
if 'MSGIEN
QUIT
Begin DoDot:2
+5 NEW NODE,PURGE,ORIG
+6 SET NODE=DEQUE(MSGIEN)
+7 SET PURGE=$PIECE(NODE,"^")
SET ORIG("IEN")=$PIECE(NODE,"^",2)
SET ORIG("ACK BY")=$PIECE(NODE,"^",3)
SET ORIG("STATUS")=$PIECE(NODE,"^",4)
+8 DO DEQUE^HLOQUE(QUEUE("FROM"),QUEUE("QUEUE"),"IN",MSGIEN)
+9 ;sets the flag to show that the app handoff was done
SET $PIECE(^HLB(MSGIEN,0),"^",19)=1
+10 ;
+11 ;update original message
+12 IF ORIG("IEN")
IF $DATA(^HLB(ORIG("IEN"),0))
Begin DoDot:3
+13 if $LENGTH(ORIG("ACK BY"))
SET $PIECE(^HLB(ORIG("IEN"),0),"^",7)=ORIG("ACK BY")
SET $PIECE(^HLB(ORIG("IEN"),0),"^",18)=1
+14 if $LENGTH(ORIG("STATUS"))
SET $PIECE(^HLB(ORIG("IEN"),0),"^",20)=ORIG("STATUS")
End DoDot:3
+15 ;
ZB2 if PURGE
Begin DoDot:3
+1 NEW STATUS
+2 SET STATUS=$PIECE(^HLB(MSGIEN,0),"^",20)
+3 if STATUS=""
SET $PIECE(^HLB(MSGIEN,0),"^",20)="SU"
SET STATUS="SU"
+4 DO SETPURGE^HLOF778A(MSGIEN,STATUS,ORIG("IEN"),ORIG("STATUS"))
End DoDot:3
End DoDot:2
+5 KILL DEQUE
SET DEQUE=0
End DoDot:1
+6 QUIT
+7 ;
ERROR ;error trap
+1 SET $ETRAP="Q:$QUIT """" Q"
+2 NEW HOUR
+3 SET HOUR=$EXTRACT($$NOW^XLFDT,1,10)
+4 SET ^TMP("HL7 ERRORS",$JOB,HOUR,$PIECE($ECODE,",",2))=$GET(^TMP("HL7 ERRORS",$JOB,HOUR,$PIECE($ECODE,",",2)))+1
+5 ;
+6 DO DEQUE()
+7 ;
+8 ;a lot of errors of the same type may indicate an endless loop
+9 ;return to the Process Manager error trap
+10 IF ($GET(^TMP("HL7 ERRORS",$JOB,HOUR,$PIECE($ECODE,",",2)))>30)
if $QUIT
QUIT ""
QUIT
+11 ;
+12 ;while debugging quit on all errors - returns to the Process Manager error trap
+13 IF $GET(^HLTMP("LOG ALL ERRORS"))
if $QUIT
QUIT ""
QUIT
+14 IF $ECODE["EDITED"
if $QUIT
QUIT ""
QUIT
+15 ;
+16 DO ^%ZTER
+17 DO UNWIND^%ZTER
+18 if $QUIT
QUIT ""
+19 QUIT
+20 ;
ERROR2 ;
+1 SET $ETRAP="Q:$QUIT """" Q"
+2 ;
+3 DO DEQUE()
+4 ;
+5 ;may need to change the status to Error
+6 Begin DoDot:1
+7 NEW NODE,RAPP,SAPP,FS,CS,REP,ESCAPE,SUBCOMP,HDR,DIR,NOW,SYS
+8 DO SYSPARMS^HLOSITE(.SYS)
+9 SET NOW=$$NOW^XLFDT
+10 SET NODE=$GET(^HLB(MSGIEN,0))
+11 if NODE=""
QUIT
+12 if $PIECE(NODE,"^",20)="ER"
QUIT
+13 SET $PIECE(NODE,"^",20)="ER"
SET $PIECE(NODE,"^",21)="APPLICATION ROUTINE ERROR"
+14 SET DIR=$SELECT($EXTRACT($PIECE(NODE,"^",4))="I":"IN",1:"OUT")
+15 IF $PIECE(NODE,"^",9)
KILL ^HLB("AD",DIR,$PIECE(NODE,"^",9),MSGIEN)
+16 SET $PIECE(NODE,"^",9)=$$FMADD^XLFDT(NOW,SYS("ERROR PURGE"))
+17 SET ^HLB(MSGIEN,0)=NODE
+18 SET ^HLB("AD",DIR,$PIECE(NODE,"^",9),MSGIEN)=""
+19 SET HDR=$GET(^HLB(MSGIEN,1))
+20 SET FS=$EXTRACT(HDR,4)
+21 if FS=""
QUIT
+22 SET CS=$EXTRACT(HDR,5)
+23 SET REP=$EXTRACT(HDR,6)
+24 SET ESCAPE=$EXTRACT(HDR,7)
+25 SET SUBCOMP=$EXTRACT(HDR,8)
+26 SET RAPP=$$DESCAPE^HLOPRS1($PIECE($PIECE(HDR,FS,5),CS),FS,CS,SUBCOMP,REP,ESCAPE)
+27 IF RAPP=""
SET RAPP="UNKNOWN"
+28 SET SAPP=$$DESCAPE^HLOPRS1($PIECE($PIECE(HDR,FS,3),CS),FS,CS,SUBCOMP,REP,ESCAPE)
+29 SET ^HLB("ERRORS",RAPP,NOW,MSGIEN)=""
+30 DO COUNT^HLOESTAT(DIR,RAPP,SAPP,"UNKNOWN")
End DoDot:1
+31 ;
+32 ;kill the apps variables
+33 Begin DoDot:1
+34 NEW ZTSK,MSGIEN,QUEUE
+35 DO KILL^XUSCLEAN
End DoDot:1
+36 ;
+37 ;release all the locks the app may have set, except Taskman lock
+38 if $DATA(ZTSK)
LOCK ^%ZTSCH("TASK",ZTSK):1
+39 if '$DATA(ZTSK)
LOCK
+40 ;reset HLO's lock
+41 LOCK +^HLTMP("HL7 RUNNING PROCESSES",$JOB):0
+42 ;return to processing the next message on the queue
+43 SET $ECODE=""
+44 ;
+45 if $QUIT
QUIT ""
+46 QUIT
ERROR3 ;error trap for application context
+1 SET $ETRAP="Q:$QUIT """" Q"
+2 DO ^%ZTER
+3 SET $ECODE=",UAPPLICATION ERROR,"
+4 ;
+5 ;drop to the ERROR2 error handler
+6 if $QUIT
QUIT ""
+7 QUIT
+8 ;
+9 ;
+10 ;
+11 ;
+12 ;