Append on 03/15/91 at 03:12 by Melinda Varian : Several people have asked me to post a small service machine implemented in Pipes, to show a way of using 'delay', 'starmsg', 'immcmd', and PIPMOD STOP. The guts of the server are hidden in a single subroutine called GETCMD: /* GETCMD REXX */ Signal On Syntax primer = '00000004* RDR FILE **** FROM' 'callpipe (end ?)', '| immcmd CMD', /* Immediate commands */ '| spec /00000004*/ 1.16 1-* next', /* As if SMSG from self */ '| f: faninany', /* Join all commands */ '| *:', /* Pass to caller */ '?', ' starmsg', /* Listen for SMSGs */ '| f:', /* Pass to caller */ '?', ' literal' primer 'startup', /* Prime the pipeline */ '| f:', /* Pass to caller */ '?', ' delaycmd', /* Timer-driven retries */ '| f:', /* Pass to caller */ '?', ' immcmd CP', /* Immediate CP command */ '| spec /CP/ 1 1-* 4', /* Build command */ '| subcom cms', /* Pass to CMS */ '?', ' immcmd SHUTDOWN', /* SHUTDOWN command */ '| spec /PIPMOD STOP/', /* Build PIPMOD STOP */ '| subcom cms' /* Pass to CMS */ GETCMD receives all kinds of input: - Commands typed on the virtual machine console are trapped by the 'immcmd' stages. If a SHUTDOWN command is typed, then a PIPMOD STOP command is given to CMS to stop the pipeline. If a CP command is typed, then it is given to CMS to pass to CP. If a command intended for the server (prefaced by 'CMD') is typed, then it is sent through the 'faninany' stage and the connector into the calling pipeline. - Commands SMSGed from other virtual machines are received by the 'starmsg' stage and are also fanned in and sent through the connector to the calling pipeline. - Messages generated by the arrival of spool files are trapped by the same 'starmsg' (all kinds of messages have been set to IUCV), so they also go to the calling pipeline. - A 'literal' stage fires once when the pipeline is first invoked. This sends a 'primer' line into the calling pipeline to get it to start processing. - Timer interrupts are generated by a subroutine called DELAYCMD, which feeds a line into GETCMD each time it has done something for which the main (calling) pipeline should be wakened. (GETCMD fans those lines in and sends them through the connector to the caller, just as it does with everything else.) Here's a portion of DELAYCMD: 'callpipe (end ?)', ' literal +24:00:00', /* Once per day */ '| dup *', '| literal 23:00:00', /* At 11pm daily */ '| delay', '| spec /CHANGE RDR CLASS K NOHOLD/', '| cp', /* Release Class K files */ '| nlocate /NO/', /* Forget it if no files */ '| spec /'primer'/ 1 / class k delay/ next' /* Fake file arrival */ '| f: faninany', /* Join all messages */ '| *:', /* Pass to GETCMD */ '?', ' literal +240:00', /* Four-hour interval */ '| dup *', '| delay', '| spec /CHANGE RDR CLASS J NOHOLD/', '| cp', /* Release Class J files */ '| nlocate /NO/', /* Forget it if no files */ '| spec /'primer'/ 1 / class j delay/ next', /* Fake file arrival */ '| f:' /* Pass to GETCMD */ '?', . . . Thus, the main pipeline starts out by invoking GETCMD: 'pipe (end ?)', 'getcmd |', . . . All its input comes from GETCMD, arriving in whatever order the various events (reader files, console commands, timer-driven events, SMSGed commands) occur and whenever they occur. The rest of the pipeline is simply an extensive decoding network that looks at the single record received from GETCMD for each event and decides what action to take in each case. This has been running for six months now under Pipes 1.0105 and has never abended or lost an interrupt. Melinda