Page 1 of 1

Submitting Jobs to Batch on Windows

Posted: Wed Aug 09, 2017 1:37 am
by jyoung
How do I submit a Function to batch?

I have a Process/Function defined that is invoked from a ServerModule to produce a PDF report.

I am trying to "batch" the report so that the user does not wait on its creation and under certain parameters it can take quite some time to finish and exceed the time out of the Server Module.

I can "call" the function just fine, but when I "submit" I loose all track of it, no tracing output appears and I have no indication that it actually ran.

This is on my local dev box so its Windows 10. I'll worry about doing the same thing for the iSeries later.

I am submitting as such:

Code: Select all

#SYS_APPLN.TraceMessageData( "Submitting the CMGSAN Report" )

submit process(CMGSANReportProcess) function(CMGSANEmailReport) exchange(#OFOFID #OFOTY #CWJTYP #wk_StartDate #wk_EndDate #wk_PreviousStartDate #wk_PreviousEndDate #wk_CountryCode #wk_Email)

#SYS_APPLN.TraceMessageData( "CMGSAN Report has been submitted" )
I get the trace output for the server module as noted in the above code block but none of the trace output for the function is logged. So I don't know if it worked, failed or just disappeared into the ether.

The docs mention the IBM i Queue Emulation
In this default environment the SUBMIT command works, but there is no inherent ability to queue the submitted jobs for deferred or serial execution.
But I am not trying to queue them or to defer execution, just submit them to run. Do I still need to emulate the queues?

Re: Submitting Jobs to Batch on Windows

Posted: Wed Aug 09, 2017 2:25 am
by jyoung
I've created the job queues as outlined in http://docs.lansa.com/14/en/LANSA015/co ... 7_0005.htm and can start the job queue as described in http://docs.lansa.com/14/en/LANSA015/co ... 7_0015.htm.
So now the submit looks like

Code: Select all

submit process(CMGSANReportProcess) function(CMGSANEmailReport) exchange(#OFOFID #OFOTY #CWJTYP #wk_StartDate #wk_EndDate #wk_PreviousStartDate #wk_PreviousEndDate #wk_CountryCode #wk_Email) job(MYJOB) jobq(QBATCH)
So now I am getting my trace output in the QBATCH folder and I can tell that the job is executing.
qbatch_folder.PNG
qbatch_folder.PNG (16.3 KiB) Viewed 5871 times
So I guess you do have to have the job queues defined after all.

Re: Submitting Jobs to Batch on Windows

Posted: Wed Aug 09, 2017 2:33 am
by atostaine
How are you tracing your server modules? We aren't using VLF.

Art

Re: Submitting Jobs to Batch on Windows

Posted: Wed Aug 09, 2017 2:49 am
by jyoung
I created a Trace Handler that looks in a data area for a YES/NO flag. I actually have two handlers one for our VLF app and one for our mobile web app.
Here is the VLFTraceHandler. Its not VLF specific, its just how I keep the two application's trace files separate.

Code: Select all

* =================================================================================================================
*
* VLF SERVER SIDE TRACE HANDLER
*
* Enables trace output on server side objects.
* Tracing is toggled via the LANSACFG/TRACE data area
* Trace files are written to *TEMP_DIR, typically
*     IBM i - /lansa_dcxpgmlib/x_lansa/tmp
*     Windows - C:\Windows\Temp
* Trace files are named VLF-Trace.YYYYMMDD.text

* -----------------------------------------------------------------------------------------------------------------
* TO USE:
*
* Define this component in your object with application scope
* define_com class(#VLFServerTraceHandler) scope(*APPLICATION)
*
* Enable tracing by setting the LANSACFG/TRACE data area to 'YES'

function options(*DIRECT)
begin_com role(*EXTENDS #PRIM_OBJT *implements #PRIM_APP.iTraceHandler)

define field(#FileHandle) type(*dec) length(3) decimals(0)
define_com class(#PRIM_ALPH) name(#Tab)

evtroutine handling(#COM_OWNER.CreateInstance)
#Tab := (09).asChar
#COM_OWNER.InstallTracing
endroutine

mthroutine name(InstallTracing) help('Plug in the trace handler to the Application') access(*private)
if (*TRACE = YES)
#SYS_APPLN.TraceHandler <= #COM_OWNER
endif

endroutine

mthroutine name(Initialize) options(*redefine) access(*private)
#COM_OWNER.OpenTraceFile
endroutine

mthroutine name(Terminate) options(*redefine) access(*private)
#COM_OWNER.CloseTraceFile
endroutine

mthroutine name(TraceMessage) help('Executed whenever #SYS_APPLN.TraceMessageData or #SYS_APPLN.TraceMessageText is used') options(*redefine) access(*private)
#COM_OWNER.WriteToFile( #ComponentName #Description #LineNumber #MessageText )
endroutine

mthroutine name(OpenTraceFile) help('Create a new trace outputfile') access(*private)
use builtin(STM_FILE_OPEN) with_args(#COM_OWNER.GetNextFile Append N Y) to_get(#FileHandle #IO$STS)
endroutine

mthroutine name(WriteToFile) help('Write an entry in the trace output file') access(*private)
define_map for(*Input) class(#PRIM_ALPH) name(#ComponentName)
define_map for(*Input) class(#PRIM_ALPH) name(#Description)
define_map for(*Input) class(#PRIM_NMBR) name(#LineNumber)
define_map for(*Input) class(#PRIM_ALPH) name(#MessageText)

define_com class(#PRIM_DAT) name(#Now)

#MessageText := #Now.now.AsLocalizedDateTime.AsString + #Tab + #ComponentName + #Tab + #LineNumber.asstring + #Tab + #MessageText

use builtin(STM_FILE_WRITE) with_args(#FileHandle #MessageText) to_get(#IO$STS)
endroutine

mthroutine name(CloseTraceFile) access(*private)
use builtin(STM_FILE_CLOSE) with_args(#FileHandle) to_get(#IO$STS)
endroutine

mthroutine name(TracingState) options(*redefine)
#MessageTracingActive := True
endroutine

mthroutine name(GetNextFile) access(*Private)
define_map for(*Result) class(#PRIM_ALPH) name(#Result)

#Result := *TEMP_DIR + "VLF-Trace" + "." + *YYYYMMDD.AsString + ".txt"
endroutine

end_com
It's similar to the trace handler here http://docs.lansa.com/14/en/lansa012/in ... 6_0025.htm.
I've modified how the trace files are written and in "InstallTracing" I use a custom System Variable "*TRACE".
The *TRACE just does a lookup to a data area LANSACFG/TRACE to determine if tracing should be enabled or not.

I find this easier to turn on and off on the IBM i than changing the file name as done in the example.

Once you have the handler defined, you drop it into your Server Module or other component

Code: Select all

define_com class(#VLFServerTraceHandler) scope(*APPLICATION)
Then all the SYS_APPLN_Trace*** messages get routed to your handler.

Its not by any means perfect and multiple requests to it will lock the file. I would love to find a way to write the trace file according to the user who is triggering it (i.e. the logged on user) but have not found a way to do such right now. That way I can have "Johns Trace File" or "Marys Trace File" etc.