- INHVCRA1 ;KAC,JKB ; 7 Mar 96 14:11; Application Server (ApS) Cont'd
- ;;3.01;BHL IHS Interfaces with GIS;;JUL 01, 2001
- ;COPYRIGHT 1991-2000 SAIC
- ;
- Q ;no top entry
- ;
- OPEN(INCHNL,INMEM,INADDR,INPORT,INIP) ; open a TCP socket
- ; Input : INCHNL (req) = will return channel of created socket or error
- ; msg if open fails, PBR
- ; INMEM ( ? ) = ?? - may be unnecessary, PBR
- ; INADDR (opt) = IP address of remote server to connect to as a
- ; client, or null to open as a server; if null,
- ; and PBR, will return address of client that
- ; connects
- ; INPORT (req) = IP port to open (client or server)
- ; INIP (req) = array of backround proc params, PBR
- ; also requires INBPN
- ; Output: void
- N INI,INSTOP
- F INI=1:1:INIP("OTRY") D OPEN^%INET(.INCHNL,.INMEM,.INADDR,INPORT,1) Q:INCHNL D WAIT^INHUVUT(INBPN,INIP("OHNG"),"",.INSTOP) Q:INSTOP
- I 'INCHNL,INSTOP S INCHNL="process signalled to quit"
- Q
- ;
- RECEIVE(INV,INCHNL,INIP,INERR,INMEM) ; read socket
- ; Input : INV (req) = location to store message, PBR
- ; INCHNL (req) = socket
- ; INIP (req) = array of backround proc params, PBR
- ; INERR (opt) = error array, PBR
- ; INMEM ( ? ) = ?? - may be unnecessary, PBR
- ; also requires INBPN,U
- ; Output: 0=ok, 1=no response, 2=failure during receive, 3=fatal err
- ; init vars
- N AP,APREC,INDONE,INORESP,INREC,INSMIN,INTTOT,INULRD,REC
- S (APREC,AP,INDONE,INORESP,INTTOT,INULRD)="",INREC="REC"
- S INSMIN=$S($P($G(^INRHSITE(1,0)),U,14):$P(^(0),U,14),1:2500)
- ; socket read loop
- F D Q:INDONE!INORESP
- .D RECV^%INET(.APREC,.INCHNL,INIP("RTO"),1)
- .; handle receive errors
- .I $D(APREC(0)) D Q
- ..; all but timeouts are fatal
- ..I APREC(0)'["TIMEOUT" S INDONE=1 Q
- ..; handle timeouts
- ..K APREC(0)
- ..S INULRD=INULRD+1 ; increment # of retries
- ..;I INULRD>INIP("RTRY") S INORESP=1 Q ; retries NOT currently active
- ..D WAIT^INHUVUT(INBPN,INIP("RHNG"),"",.INORESP) Q:INORESP
- ..S INTTOT=INTTOT+INIP("RTO")+INIP("RHNG")
- ..I INTTOT'<INIP("TMAX") S INORESP=1 Q
- .; process end of msg
- .I APREC[$C(28) D
- ..; if end of msg not clean, purge buffer (513 byte msg prob)
- ..I $P(APREC,$C(28),2)'=$C(13) N X S X="" D RECV^%INET(.X,.INCHNL,1,1)
- ..; remove end of msg sequence; set flag
- ..S APREC=$P(APREC,$C(28)),INDONE=1
- .; remove start of msg sequence
- .I APREC[$C(11) S APREC=$P(APREC,$C(11),2)
- .; quit if nothing left
- .Q:'$L(APREC)
- .; switch to global storage if short on memory
- .I $S<INSMIN,INREC'["^" K ^UTILITY("INREC",$J) M ^($J)=@INREC S INREC="^UTILITY(""INREC"","_$J_")"
- .S AP=AP+1,@INREC@(AP)=APREC,INULRD=0
- ; if fatal error
- I $D(APREC(0)) S INERR="fatal error: "_APREC(0) Q 3
- ; if no msg received
- I 'AP S INERR="no message received from remote system" Q 1
- ; if remote system timed-out
- I INORESP S INERR="remote system timed-out during transmission" Q 2
- ; msg receipt completed - parse it
- D PARSE^INHUVUT1 K @INREC
- Q 0
- ;
- LOGLOCI ; LOG LOCATION input transform (4004,9.02)
- I X=$E("GLOBAL",1,$L(X)) S X="GLOBAL" Q
- I $L(X)>50 K X Q
- I X[".DAT",$L($$OPENSEQ^%ZTFS1(X,"W")) C X Q
- D TXTPTR^INHU1(3.5,.X,.Y) S:$D(X) X=$P(Y,U)
- Q
- ;
- LOGLOCO ; LOG LOCATION output transform (4004,9.02)
- I Y?1.N,$D(^%ZIS(1,Y,0)) S Y=$P(^(0),U)
- Q
- ;
- LOG(MSG,TYP,ACK) ; log BACKGROUND PROCESS activity and errors
- ; Input : MSG (req) = status/error/debug message; status msg must be a
- ; string, error/debug msg can be a string (PBV) or
- ; an array of strings (PBR)
- ; TYP (opt) = msg type: S=status(def), E=error, or integer
- ; corresponding to level of a debug msg
- ; ACK (opt) = boolean flag; set true only when logging a
- ; positive ack (sets piece 3 of run node = $H)
- ; INBPN,U (req)
- ; INDEBUG,INDEBUGD,INHSRVR (opt)
- ; Output: void
- ; INDEBUG,INDEBUGD if not set coming in
- ; if debug on, will write to debug log (file, device or global)
- ; Local : ENUM = INTERFACE ERROR ptr
- ; T = timestamp
- ; SRVR = server number or 0 if not a multiple background proc
- I '$D(INDEBUG) D DEBUG()
- N SRVR S SRVR=+$G(INHSRVR),TYP=$G(TYP)
- ; if debugging, write to log
- I INDEBUG,INDEBUG'<TYP D
- .I $D(MSG)=1,$L(MSG) S MSG(1)=MSG
- .N J,T S J="",T=$$NOW^%ZTFDT
- .I INDEBUGD="GLOBAL" D Q
- ..N I S I=$O(^UTILITY("INDEBUG",INBPN,SRVR,$J,""),-1)
- ..F I=I+1:1 S J=$O(MSG(J)) Q:J="" S ^(I)=T_U_MSG(J) ;NAKED on ^UTILITY
- .U INDEBUGD F S J=$O(MSG(J)) Q:J="" W !,INBPN_U_SRVR_U_T_U_MSG(J)
- Q:TYP
- ; on error, log in error file and abbrev msg text to point to it
- I TYP="E" N ENUM D LOAD^INHE("","","","R","","","",.MSG,INBPN,.ENUM) S MSG="Error "_$G(ENUM)
- ; update "run" node (format: Status$H^StatusText^LastPositiveAck$H)
- I SRVR S $P(^INRHB("RUN","SRVR",INBPN,SRVR),U,1,2)=$H_U_MSG S:$G(ACK) $P(^(SRVR),U,3)=$H Q
- S $P(^INRHB("RUN",INBPN),U,1,2)=$H_U_MSG S:$G(ACK) $P(^(INBPN),U,3)=$H
- Q
- ;
- DEBUG(L) ; set debug params for a BACKGROUND PROCESS
- ; Input : L (opt) = debug level; "" = look it up (def), 0 = turn it
- ; off, positive integer = set it
- ; also expects INBPN
- ; Output: void
- ; INDEBUG = Debug Level
- ; INDEBUGD = Log Location
- ; if debug level input is null, look it up
- S INDEBUG=$S($L($G(L)):L,1:$P($G(^INTHPC(INBPN,9)),U))
- ; if debug off, close log loc if not a global, then kill var and quit
- I 'INDEBUG D Q
- .I $L($G(INDEBUGD)) D:INDEBUGD'="GLOBAL" ^%ZISC K INDEBUGD
- ; debug is on - get log loc
- S INDEBUGD=$P(^INTHPC(INBPN,9),U,2)
- ; quit if no need to open (is a global or $P)
- I "GLOBAL"[INDEBUGD S:INDEBUGD="" INDEBUGD=$P Q
- ; if a device ptr, resolve it
- I INDEBUGD,$D(^%ZIS(1,INDEBUGD,0)) S INDEBUGD=$P(^(0),U)
- ; open the device - if can't, use $P
- S IOP=INDEBUGD D ^%ZIS I POP S IOP="" D ^%ZIS
- S INDEBUGD=IO
- Q
- INHVCRA1 ;KAC,JKB ; 7 Mar 96 14:11; Application Server (ApS) Cont'd
- +1 ;;3.01;BHL IHS Interfaces with GIS;;JUL 01, 2001
- +2 ;COPYRIGHT 1991-2000 SAIC
- +3 ;
- +4 ;no top entry
- QUIT
- +5 ;
- OPEN(INCHNL,INMEM,INADDR,INPORT,INIP) ; open a TCP socket
- +1 ; Input : INCHNL (req) = will return channel of created socket or error
- +2 ; msg if open fails, PBR
- +3 ; INMEM ( ? ) = ?? - may be unnecessary, PBR
- +4 ; INADDR (opt) = IP address of remote server to connect to as a
- +5 ; client, or null to open as a server; if null,
- +6 ; and PBR, will return address of client that
- +7 ; connects
- +8 ; INPORT (req) = IP port to open (client or server)
- +9 ; INIP (req) = array of backround proc params, PBR
- +10 ; also requires INBPN
- +11 ; Output: void
- +12 NEW INI,INSTOP
- +13 FOR INI=1:1:INIP("OTRY")
- DO OPEN^%INET(.INCHNL,.INMEM,.INADDR,INPORT,1)
- IF INCHNL
- QUIT
- DO WAIT^INHUVUT(INBPN,INIP("OHNG"),"",.INSTOP)
- IF INSTOP
- QUIT
- +14 IF 'INCHNL
- IF INSTOP
- SET INCHNL="process signalled to quit"
- +15 QUIT
- +16 ;
- RECEIVE(INV,INCHNL,INIP,INERR,INMEM) ; read socket
- +1 ; Input : INV (req) = location to store message, PBR
- +2 ; INCHNL (req) = socket
- +3 ; INIP (req) = array of backround proc params, PBR
- +4 ; INERR (opt) = error array, PBR
- +5 ; INMEM ( ? ) = ?? - may be unnecessary, PBR
- +6 ; also requires INBPN,U
- +7 ; Output: 0=ok, 1=no response, 2=failure during receive, 3=fatal err
- +8 ; init vars
- +9 NEW AP,APREC,INDONE,INORESP,INREC,INSMIN,INTTOT,INULRD,REC
- +10 SET (APREC,AP,INDONE,INORESP,INTTOT,INULRD)=""
- SET INREC="REC"
- +11 SET INSMIN=$SELECT($PIECE($GET(^INRHSITE(1,0)),U,14):$PIECE(^(0),U,14),1:2500)
- +12 ; socket read loop
- +13 FOR
- Begin DoDot:1
- +14 DO RECV^%INET(.APREC,.INCHNL,INIP("RTO"),1)
- +15 ; handle receive errors
- +16 IF $DATA(APREC(0))
- Begin DoDot:2
- +17 ; all but timeouts are fatal
- +18 IF APREC(0)'["TIMEOUT"
- SET INDONE=1
- QUIT
- +19 ; handle timeouts
- +20 KILL APREC(0)
- +21 ; increment # of retries
- SET INULRD=INULRD+1
- +22 ;I INULRD>INIP("RTRY") S INORESP=1 Q ; retries NOT currently active
- +23 DO WAIT^INHUVUT(INBPN,INIP("RHNG"),"",.INORESP)
- IF INORESP
- QUIT
- +24 SET INTTOT=INTTOT+INIP("RTO")+INIP("RHNG")
- +25 IF INTTOT'<INIP("TMAX")
- SET INORESP=1
- QUIT
- End DoDot:2
- QUIT
- +26 ; process end of msg
- +27 IF APREC[$CHAR(28)
- Begin DoDot:2
- +28 ; if end of msg not clean, purge buffer (513 byte msg prob)
- +29 IF $PIECE(APREC,$CHAR(28),2)'=$CHAR(13)
- NEW X
- SET X=""
- DO RECV^%INET(.X,.INCHNL,1,1)
- +30 ; remove end of msg sequence; set flag
- +31 SET APREC=$PIECE(APREC,$CHAR(28))
- SET INDONE=1
- End DoDot:2
- +32 ; remove start of msg sequence
- +33 IF APREC[$CHAR(11)
- SET APREC=$PIECE(APREC,$CHAR(11),2)
- +34 ; quit if nothing left
- +35 IF '$LENGTH(APREC)
- QUIT
- +36 ; switch to global storage if short on memory
- +37 IF $STORAGE<INSMIN
- IF INREC'["^"
- KILL ^UTILITY("INREC",$JOB)
- MERGE ^($JOB)=@INREC
- SET INREC="^UTILITY(""INREC"","_$JOB_")"
- +38 SET AP=AP+1
- SET @INREC@(AP)=APREC
- SET INULRD=0
- End DoDot:1
- IF INDONE!INORESP
- QUIT
- +39 ; if fatal error
- +40 IF $DATA(APREC(0))
- SET INERR="fatal error: "_APREC(0)
- QUIT 3
- +41 ; if no msg received
- +42 IF 'AP
- SET INERR="no message received from remote system"
- QUIT 1
- +43 ; if remote system timed-out
- +44 IF INORESP
- SET INERR="remote system timed-out during transmission"
- QUIT 2
- +45 ; msg receipt completed - parse it
- +46 DO PARSE^INHUVUT1
- KILL @INREC
- +47 QUIT 0
- +48 ;
- LOGLOCI ; LOG LOCATION input transform (4004,9.02)
- +1 IF X=$EXTRACT("GLOBAL",1,$LENGTH(X))
- SET X="GLOBAL"
- QUIT
- +2 IF $LENGTH(X)>50
- KILL X
- QUIT
- +3 IF X[".DAT"
- IF $LENGTH($$OPENSEQ^%ZTFS1(X,"W"))
- CLOSE X
- QUIT
- +4 DO TXTPTR^INHU1(3.5,.X,.Y)
- IF $DATA(X)
- SET X=$PIECE(Y,U)
- +5 QUIT
- +6 ;
- LOGLOCO ; LOG LOCATION output transform (4004,9.02)
- +1 IF Y?1.N
- IF $DATA(^%ZIS(1,Y,0))
- SET Y=$PIECE(^(0),U)
- +2 QUIT
- +3 ;
- LOG(MSG,TYP,ACK) ; log BACKGROUND PROCESS activity and errors
- +1 ; Input : MSG (req) = status/error/debug message; status msg must be a
- +2 ; string, error/debug msg can be a string (PBV) or
- +3 ; an array of strings (PBR)
- +4 ; TYP (opt) = msg type: S=status(def), E=error, or integer
- +5 ; corresponding to level of a debug msg
- +6 ; ACK (opt) = boolean flag; set true only when logging a
- +7 ; positive ack (sets piece 3 of run node = $H)
- +8 ; INBPN,U (req)
- +9 ; INDEBUG,INDEBUGD,INHSRVR (opt)
- +10 ; Output: void
- +11 ; INDEBUG,INDEBUGD if not set coming in
- +12 ; if debug on, will write to debug log (file, device or global)
- +13 ; Local : ENUM = INTERFACE ERROR ptr
- +14 ; T = timestamp
- +15 ; SRVR = server number or 0 if not a multiple background proc
- +16 IF '$DATA(INDEBUG)
- DO DEBUG()
- +17 NEW SRVR
- SET SRVR=+$GET(INHSRVR)
- SET TYP=$GET(TYP)
- +18 ; if debugging, write to log
- +19 IF INDEBUG
- IF INDEBUG'<TYP
- Begin DoDot:1
- +20 IF $DATA(MSG)=1
- IF $LENGTH(MSG)
- SET MSG(1)=MSG
- +21 NEW J,T
- SET J=""
- SET T=$$NOW^%ZTFDT
- +22 IF INDEBUGD="GLOBAL"
- Begin DoDot:2
- +23 NEW I
- SET I=$ORDER(^UTILITY("INDEBUG",INBPN,SRVR,$JOB,""),-1)
- +24 ;NAKED on ^UTILITY
- FOR I=I+1:1
- SET J=$ORDER(MSG(J))
- IF J=""
- QUIT
- SET ^(I)=T_U_MSG(J)
- End DoDot:2
- QUIT
- +25 USE INDEBUGD
- FOR
- SET J=$ORDER(MSG(J))
- IF J=""
- QUIT
- WRITE !,INBPN_U_SRVR_U_T_U_MSG(J)
- End DoDot:1
- +26 IF TYP
- QUIT
- +27 ; on error, log in error file and abbrev msg text to point to it
- +28 IF TYP="E"
- NEW ENUM
- DO LOAD^INHE("","","","R","","","",.MSG,INBPN,.ENUM)
- SET MSG="Error "_$GET(ENUM)
- +29 ; update "run" node (format: Status$H^StatusText^LastPositiveAck$H)
- +30 IF SRVR
- SET $PIECE(^INRHB("RUN","SRVR",INBPN,SRVR),U,1,2)=$HOROLOG_U_MSG
- IF $GET(ACK)
- SET $PIECE(^(SRVR),U,3)=$HOROLOG
- QUIT
- +31 SET $PIECE(^INRHB("RUN",INBPN),U,1,2)=$HOROLOG_U_MSG
- IF $GET(ACK)
- SET $PIECE(^(INBPN),U,3)=$HOROLOG
- +32 QUIT
- +33 ;
- DEBUG(L) ; set debug params for a BACKGROUND PROCESS
- +1 ; Input : L (opt) = debug level; "" = look it up (def), 0 = turn it
- +2 ; off, positive integer = set it
- +3 ; also expects INBPN
- +4 ; Output: void
- +5 ; INDEBUG = Debug Level
- +6 ; INDEBUGD = Log Location
- +7 ; if debug level input is null, look it up
- +8 SET INDEBUG=$SELECT($LENGTH($GET(L)):L,1:$PIECE($GET(^INTHPC(INBPN,9)),U))
- +9 ; if debug off, close log loc if not a global, then kill var and quit
- +10 IF 'INDEBUG
- Begin DoDot:1
- +11 IF $LENGTH($GET(INDEBUGD))
- IF INDEBUGD'="GLOBAL"
- DO ^%ZISC
- KILL INDEBUGD
- End DoDot:1
- QUIT
- +12 ; debug is on - get log loc
- +13 SET INDEBUGD=$PIECE(^INTHPC(INBPN,9),U,2)
- +14 ; quit if no need to open (is a global or $P)
- +15 IF "GLOBAL"[INDEBUGD
- IF INDEBUGD=""
- SET INDEBUGD=$PRINCIPAL
- QUIT
- +16 ; if a device ptr, resolve it
- +17 IF INDEBUGD
- IF $DATA(^%ZIS(1,INDEBUGD,0))
- SET INDEBUGD=$PIECE(^(0),U)
- +18 ; open the device - if can't, use $P
- +19 SET IOP=INDEBUGD
- DO ^%ZIS
- IF POP
- SET IOP=""
- DO ^%ZIS
- +20 SET INDEBUGD=IO
- +21 QUIT