TCP/IP printer writers fail to start at IPL time

From Try-AS/400
Revision as of 17:19, 7 December 2023 by PoC (talk | contribs) (→‎Possible solution: Typo)
Jump to navigation Jump to search

When TCP/IP IPDS printers connected over LAN have been configured, the associated printer writers might fail to start at IPL time.

This does not affect remote *outq objects. Possible reasons:

  • they don't try to connect to the respective printers when their writers are started,
  • they retry when the connection fails.

Contrary, IPDS printers are in tight control by the host's printing system.

Details

This is a timing issue, appearing because TCP/IP is started asynchronously in course of the IPL process. If the machine is fast enough to have the interfaces started before the IPL process advances to starting the printer writers, everything is fine. If not, the writers fail to start and has to be started manually at a later point in time.

Possible solution

Printer writers are started with CALL PGM(QSYS/QWCSWTRS) in the respective startup procedure, usually QSTRUP. See See also below for details.

It might be easy to add a static wait time to the respective startup procedure, at the right spot. Personally, I don't like this approach:

  • the delay might be too long and unnecessarily lengthen IPL time,
  • the delay might be too short and doesn't solve the problem,
  • the delay might be just right for now, until other changes are introduced, affecting startup timing.

My recommendation is to introduce a check in a loop which exits as soon as either the host is reachable or "enough" tries have been attempted.

First, some additional variables need to be declared. The declarations must be inserted before any non-declaration statements.

DCL VAR(&WTRHOST) TYPE(*CHAR) LEN(13) VALUE('192.168.1.33')
DCL VAR(&ITERCOUNT) TYPE(*DEC) LEN(2 0) VALUE(0)
DCL VAR(&ITERTXT) TYPE(*CHAR) LEN(2)
  • &wtrhost should be an IP address. In theory, if TCP/IP startup hasn't progressed to allow DNS lookups, the outcome might be the same, but might add additional delay (resolver timeouts).
  • &itertext is necessary because CL does not allow to mix text and numeric variables for output.

This is the actual code block. Lines preceded by | are to be inserted, while the other lines are shown for context only.

 DONE:
      QSYS/RTVSYSVAL SYSVAL(QSTRPRTWTR) RTNVAR(&STRWTRS)
      IF COND(&STRWTRS = '0') THEN(GOTO CMDLBL(NOWTRS))
|
|     /* TCP/IP startup takes some time, so not all writers come up. */
|     LOOP:
|     CHGVAR VAR(&ITERCOUNT) VALUE(&ITERCOUNT + 1)
|
|     /* Don't try infinitely. */
|     IF COND(&ITERCOUNT *GE 40) THEN(DO)
|     CHGVAR VAR(&ITERTXT) VALUE(&ITERCOUNT)
|     SNDPGMMSG MSG('Timeout after' *BCAT &ITERTXT *BCAT 'tries') TOPGMQ(*PRV)
|     GOTO CMDLBL(NOWTRS)
|     ENDDO /* If Cond */
|
|     PING RMTSYS(&WTRHOST) MSGMODE(*QUIET *ESCAPE) PKTLEN(64) NBRPKT(1)
|     MONMSG MSGID(TCP3210) EXEC(DO)
|     DLYJOB DLY(3)
|     GOTO CMDLBL(LOOP)
|     ENDDO /* Monmsg */
|
      CALL PGM(QSYS/QWCSWTRS)
      MONMSG MSGID(CPF0000)
 NOWTRS:
      RETURN
      CHGVAR VAR(&CPYR) VALUE(&CPYR)
      ENDPGM

This solution is also not perfect, because the IP address is hardcoded in the script. But it at least adapts dynamically to the availability of the printer on the network.

See also