Passing an array to a class method on a job command
hi-
Can someone give me an example of how to JOB a class method that requires an array of values to be passed to it by reference.
This is what I tried, but am getting compile errors because of the .params
job ##class(%SYSTEM.OBJ.FM2Class).All(.params)::5
Any thoughts on how to accomplish this, the simplest way. I would like to avoid writing all of this to some global and having to write some wrapper to pick it up and then call the class method, which I certainly could do. but is this the only way to do it?
Comments
Looking further, it would seem that we can not pass an array as an argument to a JOB command so I need to come up with a new way to get this array of parameters to the JOBed process.
If you know all possible arguments just create a wrapper method that accepts all arguments and job that.
Eduard, there are dozens. params contains any number of values, not all required.
Thinking the easiest way may be to just save params to a subscripted global, job off a wrapper, passing the subscript. Grab the array out of the global and then start the class method, killing the global.
Thanks Robert-
I dont think I have a choice here. the All method of the %SYSTEM.OBJ.FM2Class expects the array to be passed by reference. I did come up with a solution though....
/// Run FM2Class in background fo rnewly created namespace
ClassMethod ConfigFM2Class(Namespace As %String, LocalPath As %String) As %String{new $namespace set curnsp=$namespace,$namespace=Namespacewrite !,"Starting FM2Class for Namespace ",Namespace," in background"; Build Up Parametersset params("childTableNameFormat")="SUB_<FILENAME>,<FILENUMBER>" set params("compile")=1 set params("compileQSpec")="/display=all/lock=0" set params("dateType")="%Library.FilemanDate" set params("datetimeType")="%Library.FilemanTimeStamp" set params("deleteQSpec")="/display=all" set params("display")=0 set params("expandPointers")=0 set params("expandSetOfCodes")=0 set params("extendedMapping")="" set params("fieldNameFormat")="Exact" set params("ienFieldName")="IEN" set params("logFile")=LocalPath_"fm2class_"_Namespace_".log" set params("nameLength")=180 set params("owner")="_SYSTEM" set params("package")="VISTA" set params("readonly")=0 set params("recursion")=2 set params("requiredType")=0 set params("retainClass")=1 set params("setOfCodesEnum")=1 set params("strictData")=0 set params("superClasses")="" set params("tableNameFormat")="<FILENAME>,<FILENUMBER>" set params("variablePointerValueField")=0 set params("wpIsList")=0 kill ^UTILITY(Namespace,$j,"ISC.HealthConnect.Installer") merge ^UTILITY($j,"ISC.HealthConnect.Installer")=params set $namespace=curnsp job ##class(ISC.HealthConnect.Installer).jobfm(Namespace,$j)::5set zSC=1if '$t set zSC=0quit zSC}ClassMethod jobfm(Namespace,job){;Startup FM2Classnew $namespace set $namespace=Namespacemerge params=^UTILITY(job,"ISC.HealthConnect.Installer")kill ^UTILITY(job,"ISC.HealthConnect.Installer")do ##class(%SYSTEM.OBJ.FM2Class).All(.params)quit}
Definately agree. Pretty sure my UTILITY global is mapped to CACHETEMP.
Hi Ken,
There is an easier way.
Instead of fiddling around with unpredictable params you just pass your whole symbol table = local variables
to your background job like this and use what you need in background
JOB ##class(%SYSTEM.OBJ.FM2Class).All():(:1):5
look for process-params + switch here
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…
It's better to use CACHETEMP mapped global, e.g. ^CacheTempUserYourGlobal($job,...).
BTW there is another option: having a wrapper job, pass it an array serialized to JSON, other steps are evidient. I used it in one of my projects, and it was quicker than using of ^CacheTemp* intermediate global, while performance gain was not too sufficient (AFAIR)
The approach with a global is apparently easier, so I'd use it if performance would not of great importantance.
For passing array by reference try to use the class $system.WorkMgr instead of job.
Sample:
Class demo.test [ Abstract ]
{
ClassMethod Test(array) As %Status
{
k ^CacheTempUser.dbg
m ^CacheTempUser.dbg($zp)=array
s ^CacheTempUser.dbg($zp,"$j")=$j
q $$$OK
}
}
demo()
n queue,arr
s arr(1)="qwe"
s arr(2)="asd"
w "$j = ",$j,!
s queue=$system.WorkMgr.Initialize("/multicompile=1",,1)
d queue.Queue("##class(demo.test).Test",.arr)
d queue.WaitForComplete()
zw ^CacheTempUser.dbg
qResult:
USER>d ^demo $j = 7600 ^CacheTempUser.dbg(8488,1)="qwe" ^CacheTempUser.dbg(8488,2)="asd" ^CacheTempUser.dbg(8488,"$j")=8348
This was not the exact requirement i had. But using JOB there are issues handling files, specially in APPEND mode.
Using this workMgr, its fantastic. Its the best way to SPAWNS multiple jobs and get your work done.
A big THANK YOU! Save my last 2 weeks of effort.