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?

  • 0
  • 0
  • 403
  • 6
  • 2

Answers

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=...

 

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=Namespace
write !,"Starting FM2Class for Namespace ",Namespace," in background"
; Build Up Parameters
set 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)::5
set zSC=1
if '$t set zSC=0
quit zSC
}
ClassMethod jobfm(Namespace,job)
{
;Startup FM2Class
new $namespace set $namespace=Namespace
merge params=^UTILITY(job,"ISC.HealthConnect.Installer")
kill ^UTILITY(job,"ISC.HealthConnect.Installer")
do ##class(%SYSTEM.OBJ.FM2Class).All(.params)
quit

}

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.

Definately agree.  Pretty sure my UTILITY global is mapped to CACHETEMP.

 

For passing array by reference try to use the class $system.WorkMgr instead of job.

Sample:

Class demo.test Abstract ]
{

ClassMethod Test(arrayAs %Status
{
  ^CacheTempUser.dbg
  ^CacheTempUser.dbg($zp)=array
  ^CacheTempUser.dbg($zp,"$j")=$j
  q $$$OK
}

}

demo()
  queue,arr

  arr(1)="qwe"
  arr(2)="asd"
  
  "$j = ",$j,!
  queue=$system.WorkMgr.Initialize("/multicompile=1",,1)
  queue.Queue("##class(demo.test).Test",.arr)
  queue.WaitForComplete()
  
  zw ^CacheTempUser.dbg
  q

Result:

USER>^demo
$j = 7600
^CacheTempUser.dbg(8488,1)="qwe"
^CacheTempUser.dbg(8488,2)="asd"
^CacheTempUser.dbg(8488,"$j")=8348

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.