Question
· Jun 23, 2021

Ens.BusinessProcessBPL: context variable is being cleared after a synchronous call to a Business Operation

Hello,

I have a Business Process where I am receiving a JSON payload in the "Body" property of the my request class. I defined a context variable as an object of a class that represents the JSON schema I expect to receive and load the JSON payload in that context variable.

e.g.

/// BPL Definition
XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl]
{
<process language='objectscript' request='mapi.core.msg.rq.RestBusinessServiceRequest' response='mapi.core.msg.rp.RestBusinessServiceResponse' height='2000' width='2000' >
<context>
<property name='cm' type='mapi.exchange.msg.Communication' instantiate='1'/>
</context>
<sequence xend='200' yend='450' >
<code name='Map request payload' xpos='200' ypos='250' >
<annotation><![CDATA[Map request body to mapi.exchange.msg.communication]]></annotation>
<![CDATA[
cmReq={}.%FromJSON(request.Body)
   status = context.cm.%JSONImport(cmReq)
 ]]>
</code>

...

My mapi.exchange.msg.communication class has a property called Recipients which is a list.

I need to loop through the recipients and invoke a Business Operation "Send Email" for each recipient. Here is the example of syntax I use,

<foreach name='Process Recipients' property='context.cm.Recipientkey='context.keyxpos='200' ypos='350' xend='200' yend='782' >
<call name='Send Email' target='Send Email' async='0' xpos='200' ypos='450' >

<request type='mapi.exchange.msg.communication.rq.Email>
<assign property="callrequestvalue="context.cm.Recipient.GetAt(key)action="set" />
</request>
<response type='mapi.exchange.msg.CommonPostResponse>
</response>

</call>

</foreach>

 

After the call to BO, it seems like my conext.cm variable gets cleared and <foreach> fails with <INVALID OREF> when trying to do .Next() on my cm.Recipient property. Any ideas on what I am doing wrong here?

Note: if I make an asynchronous call to "Send Email" then context variable is not cleared and my process works but I need the call to "Send Email" to be synchronous.

Regards,

Utsavi

Product version: IRIS 2020.1
Discussion (4)0
Log in or sign up to continue

Here is the section in the docs that explains why this is happening and why @Eduard Lebedyuk asked if that class is persistent.
 

Business Process Execution Context

The life cycle of a business process requires it to have certain state information saved to disk and restored from disk, whenever the business process suspends or resumes execution. This feature is especially important for long-running business processes, which may take days or weeks to complete.

A BPL business process supports the business process life cycle with a group of variables known as the execution context. InterSystems IRIS automatically save the variables in the execution context and restores them each time the BPL business process suspends and resumes execution.

Thank you Marc and Eduard for your reply. After spending some time I figured what you both have pointed i.e the class needs to be persistent.

Hi Eduard, 

regarding your comment around moving JSON parsing to BS, is there a reason for doing so? 

I have a common business service which can invoke multiple different Business processes based on a parameter. that is why it uses the common class mapi.core.msg.rq.RestBusinessServiceRequest to pass on request data to the BP and let BP do the specifics. 

Regards,

Utsavi

regarding your comment around moving JSON parsing to BS, is there a reason for doing so?  

In general it might be preferable to move from less structured data (JSON) to more structured data (Objects) as fast and as early in your processing pipeline as possible.

The reasons for it are varied but include:

  • Ability to query fields via SQL
  • Object access with defined properties anywhere downstream
  • Ability to build analytics on that data
  • Fail fast (in the case of parsing errors)

So in your case I would have structured it like this:

  • Business Service accepts JSON and parses it into one of the several classes
  • Business Service calls Business Routing Rule where target Business Process is determined and the message is sent
  • Business Process does not have parsing logic and just processes messages

It's also advantageous to move all parsing logic is in one place (Business Service) as it minimizes the amount of code written and frees Business Processes from the more low-level technical tasks which usually obfuscate the more high-level intent of a Business Process.