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.