Experimenting further with monitor input, output and error output and the times
at which the
monitors seem to be used.
Here is the command (a Rexx program named 'testAbit.rex', note the "call
lineout 'stderr:', ..."
statements in it):
/call lineout "stderr:", "0) testAbit.rex, START at:" pp(.dateTime~new)
/parse source . . fullName
fileName=filespec('name',fullName)
signal on notready
sleepTime=.25
do i=1
parse linein val
/call lineout "stderr:", "1) testAbit.rex: val~length="val~length
".dateTime~new="pp(.dateTime~new)/
say "2) testAbit.rex: val~length="val~length say "<-".dateTime~new "|"
fileName": 'parse linein
val':" pp(val)"->" end
notready:
/call lineout "stderr:", "9) testAbit.rex, END at:" pp(.dateTime~new)/
::routine pp
return "["arg(1)"]"
The input comes from an input monitor that makes sure that each LINEIN
invocation will return data
with a length between 1.200.089 and 1.600.089 bytes (each well over one MB).
Each LINEIN invocation
gets timestamped. Each invocation of LINEIN will cause a sysSleep between 0.000
and 0.333 before
returning the data chunk.
The output and error monitor's LINEOUT invocations are time-stamped as well.
The ADDRESS-WITH command in the Rexx program "useTestAbit.rex" looks like:
address "" "rexx testAbit.rex" with input using (inMonitor) output using
(outMonitor) error using (errMonitor)
With this setup one can observe that while the command gets addressed:
* the command seems to get blocked when it accesses "stdin:" for the first
time
o it seems that Rexx does not return in this case and waits until all
LINEIN invocations got
processed and LINEIN issues a "raise notready" before submitting
"stdin:" data to the command
o the expecation would be that LINEIN's returned data is fed immediately
to the command
reading from 'stdin:', allowing the command to process it immediately
(at least as fast as
data is ready)
+ the debug output while the addressed command is executed would then
show the input
monitor's LINEIN invocation interweaved with output monitor LINEOUT
and other input
monitor LINEIN invocations [plus interweaved with error monitor
LINEOUT invocations from
the command]
* the output monitor's LINEOUT method gets invoked while the command
processes its input data in
the loop
o the error monitor's LINEOUT method does *not* get invoked at this
time, although it is part
of the processing within the loop to issue debug messages as can be
seen in the Rexx program
above (output to "stderr:")
* the error monitor's LINEOUT method seems to not get invoked as long as the
command is processing
and sending the output monitor LINEOUT messages
o hence the error monitor's LINEOUT method gets invoked at the end of the
command processing,
after any output monitor processing was concluded, rather than in
"real-time" (right before
returning from address-with)
+ in this use case I would have expected that the monitor object's
LINEIN (input monitor)
and LINEOUT (output and error monitors) methods get invoked
interweavedly, at the time
data is fetched from or sent to them
Is it possible to get the monitor invocations in "real-time" in ooRexx, i.e. at
the time when Rexx
interacts with these?
---rony
P.S.: This is on Windows 7 (64-bit version of ooRexx).
P.P.S.: Here are two programs used for testing monitors:
Command "testAbit.rex":
---------------------------- cut here (command "testAbit.rex")
---------------------------------------------
call lineout "stderr:", "0) testAbit.rex, START at:" pp(.dateTime~new)
parse source . . fullName
fileName=filespec('name',fullName)
signal on notready
sleepTime=.25
do i=1
parse linein val
call lineout "stderr:", "1) testAbit.rex: val~length="val~length
".dateTime~new="pp(.dateTime~new)
say "2) testAbit.rex: val~length="val~length
say "<-".dateTime~new "|" fileName": 'parse linein val':" pp(val)"->"
end
notready:
call lineout "stderr:", "9) testAbit.rex, END at:" pp(.dateTime~new)
::routine pp
return "["arg(1)"]"
---------------------------- cut here
----------------------------------------------------------------------
Rexx program to use the above command using ADDRESS-WITH (debug output expects
a very wide command line window, > 150 cols):
---------------------------- cut here (command "useTestAbit.rex")
------------------------------------------
-- define test data for input monitor (RexxQueue has no 'of'-method, unlike
Queue)
rxq=.rexxQueue~new
rxq~queue("first line"); rxq~queue("| second line"); rxq~queue("| third
line")
rxq~queue("| fourth line"); rxq~queue("| fifth line"); rxq~queue("| sixth
line")
rxq~queue("| seventh line"); rxq~queue("| eight line"); rxq~queue("| ninth
line")
rxq~queue("| tenth line")
-- defines monitors to be used for stdin, stdout, stderr
inMonitor=.monitor~new(.myInput~new(.array~new, rxq))
outMonitor=.monitor~new(.myOutput~new(.array~new))
errMonitor=.monitor~new(.myErrorOutput ~new(.array~new))
w=129 -- width for centering
cmd='"rexx testAbit.rex" with input using (inMonitor) output using (outMonitor)
error using (errMonitor)'
say
say "---> BEFORE running command"
say "->" center(cmd,w,"=")
address "" "rexx testAbit.rex" with input using (inMonitor) output using
(outMonitor) error using (errMonitor)
say "<-" center(cmd,w,"=")
say "<--- AFTER running command, rc="rc
say
-- now display the logged items
say; say "-"~copies(79);
call dumpLog inMonitor; say "-"~copies(79); say
call dumpLog outMonitor; say "-"~copies(79); say
call dumpLog errMonitor; say "-"~copies(79); say
/* ============================================= */
::class "myInput"
::attribute log -- log array
::attribute count
::method init
expose log thisClzName rxq count
use strict arg log, rxq
thisClzName=self~class~id
count=0
::method linein
expose log thisClzName rxq count
val=rxq~pull
count+=1
if val=.nil then raise notready
val=(val". ")~copies(100000)
sleepTime=format(random(0,333)/1000,,3)
dt=.dateTime~new
str=thisClzName "#" format(count,4)":"
pp(dt"+"sleepTime"="dt~addSeconds(sleepTime))",received="pp(val,"{","}")
call syssleep random(0,333)/1000
call lineout "stderr:", "--->" ellipsis(str) "<---"
log~append(str)
return str
/* ============================================= */
::class "myOutput"
::attribute log
::method init
expose log thisClzName
use strict arg log
thisClzName=self~class~id
::method lineout
expose log thisClzName
use arg val
dt=.dateTime~new
str=thisClzName pp(dt)",received="pp(val,"{","}")
call lineout "stderr:", "--->" ellipsis(str) "<---"
log~append(str)
/* ============================================= */
::class "myErrorOutput" subclass myOutput
::method init
expose log thisClzName
use arg log
forward class (super) continue
thisClzName=self~class~id
::method lineout
expose log thisClzName
use arg val
dt=.dateTime~new
str=thisClzName pp(dt)",received="pp(val,"{","}")
call lineout "stderr:", "--->" ellipsis(str) "<---"
log~append(str)
/* ============================================= */
::routine pp
use strict arg val, leftQuote="[", rightQuote="]"
return leftQuote || val || rightQuote
/* ============================================= */
::routine dumpLog
use strict arg mon
log=mon~log
id=mon~current~class~id
say id"~log, items="pp(log~items)", content:"
say id", items="pp(log~items)", content:"
say
do line over log
say ellipsis(line)
end
/* ============================================= */
::routine ellipsis -- if string is longer, cut it off, supply trailing
ellipsis
use arg val, maxWidth=140, ellipsis="..."
if val~length<=maxWidth then return val
return val~left(maxWidth-ellipsis~length) || ellipsis
---------------------------- cut here
----------------------------------------------------------------------
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel