Back in 2011 I blogged "Adding latency during service development for backend simulation":
https://www.ibm.com/developerworks/community/blogs/HermannSW/entry/adding_latency_during_service_development_for_backend_simulation94

I used <dp:url-open> against an unreachable target with timeout specifying the delay in seconds.


In 2012 I blogged "Adding sub-second latency with firmware >= 5.0.0.4":
https://www.ibm.com/developerworks/community/blogs/HermannSW/entry/adding_sub_second_latency_with_firmware_5_0_0_4

I misused "xc10:" target with <dp:url-open>" to get millisecond precision delays.

 

There is no built in delay for good reason -- be careful with what you do!

 

On the weekend I learned how to do it correctly in nodejs in Jeff's blog:
https://codingwithspike.wordpress.com/2018/03/10/making-settimeout-an-async-await-function/


First I wanted to get it working with an older (v6) nodejs version and found how to do that using asyncawait module:
https://twitter.com/HermannSW/status/1068845568053731328


It turned out that nothing special is needed for DataPower GatewayScript, Jeff's posting directly works!

I modified it a bit for DataPower, and added code that verifies that indeed the synchronous wait works by returning the measured delay:

$ cat sync_wait.js 
async function wait(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

session.input.readAsJSON(async function(error,json){
  var t0 = new Date().getTime();
  await wait(json);
  var t1 = new Date().getTime();
  session.output.write((t1-t0)+"ms");
});

 

Here you can see it:

$ coproc2 sync_wait.js <(echo '1234') http://dp3-l3:2227; echo
1235ms

$ coproc2 sync_wait.js <(echo '2000') http://dp3-l3:2227; echo
2000ms

 

 

"await wait()" needs to be run inside an async function -- I just made the readAsJSON callback async.
I did choose readAsJSON() because GatewayScript implements JSON rfc7159 allowing any top level element, here a number.

 

Next I wanted to make use of this synchronous wait in DataPower XSLT as well via "dp:gatewayScript()".

I stored "wait.js" into "local:" folder, only changing interface from JSON to XML:

$ diff sync_wait.js wait.js 
7c7
< session.input.readAsJSON(async function(error,json){
---
> session.input.readAsXML(async function(error,nodelist){
9c9
<   await wait(json);
---
>   await wait( parseInt(nodelist.item(0).textContent) );

 

 

Now wait.xsl can just call out to "local:///wait.js" for synchronous delay at millisecond precision:

$ cat wait.xsl
<xsl:stylesheet version='1.0'
  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
  xmlns:dp='http://www.datapower.com/extensions'
  extension-element-prefixes='dp'
>
  <xsl:template match='/'>
    <xsl:copy-of select="dp:gatewayscript('local:///wait.js', ., false())"/>

    <xsl:variable name="d">2345</xsl:variable>
    <xsl:copy-of select="dp:gatewayscript('local:///wait.js', $d, false())"/>
  </xsl:template>

</xsl:stylesheet> 

 

Here you see output for passed as well as XSLT coded delay values measured:

$ coproc2 wait.xsl <(echo '<t>2000</t>') http://dp3-l3:2223; echo
2000ms2345ms

 

 

Again, be careful with what you use this synchronous wait for,

Hermann.