0

Using the example from Azure for creating a Durable Function (https://learn.microsoft.com/en-us/azure/azure-functions/durable/quickstart-js-vscode) , I have a working example of the Orchestrator passing each child process a JSON Document that I manually create in the code. However when I attempt to call a function that returns a Promise from within the Orchestrator I get an error as seen in the code below. The sleep function is just mock of the call to the DB that occurs in that the call to the Azure Cosmos DB is wrapped inside a Promise and returns when it has all the documents.

QUESTION -- Is there a means of making the Orchestrator wait for the my sleep function to resolve it's Promise before starting the Chaining Pattern?

/*WORKING EXAMPLE*/
const df = require('durable-functions');

module.exports = df.orchestrator(function*(context){
context.log("Starting chain sample");

let output = [];

context.log("MERGED DOC--START:");

let mergedDoc = {/*SOME MANUALLY CREATED JSON GOES HERE*/};

context.log("MERGED DOC:--EMD");
//let mergedDoc = {};
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-1","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-2","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-2","data":mergedDoc}));


return output;
});

+++++++++++++++++++++++++++

/*FAILING EXAMPLE*/
const df = require('durable-functions');
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
module.exports = df.orchestrator(function*(context){
context.log("Starting chain sample");

let output = [];
await sleep(5000);
let mergedDoc = {};
/*
ERROR FROM CONSOLE
await sleep(5000);
^^^^

SyntaxError: Unexpected identifier
  at createScript (vm.js:80:10)
  at Object.runInThisContext (vm.js:139:10)
  at Module._compile (module.js:607:28)
*/
context.log("MERGED DOC:" + mergedDoc);
//let mergedDoc = {};
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-1","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-2","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-3","data":mergedDoc}));4
return output;});
Ad Astra
  • 75
  • 1
  • 7
  • Doesn't look possible. To sleep you need to be in a asynchronous function. So a callback or a promise. And generators are synchronous. There are ways to wrap generators in promises. Unless the df.orchestrator() method also accepts promises I don't think it's possible in your case. – grimurd Jun 24 '19 at 22:03
  • You could wrap the df.orchestrator method in a async function and sleep before you call df.orchestrator() – grimurd Jun 24 '19 at 22:05
  • Thanks for the suggestion. I found a means to accomplish this task by adding a new "STEP", Step-0, whose job was to perform the Asynchronous Function. Also it turns out that I could modify the result of the "E1-SayHello" code to return back data such that upon completing "Step-0" I would just need to set mergedDoc to the first value in the output array. `output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEO-0","data":{}})); mergedDoc = output[0]; output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-1","data":mergedDoc}));` – Ad Astra Jun 25 '19 at 17:03

1 Answers1

0

Resolution:

const df = require('durable-functions');

module.exports = df.orchestrator(function*(context){
context.log("Starting chain sample");

let output = [];
let mergedDoc = {};

/*
Add code into the E1_SayHello function for STEP-0 to perform the asych call and return the results
back to the Orchestrator.  Since this is the Chaining Pattern STEP-1 won't execute until STEP-0 has
completed.  The result is that my E1_SayHello code has a list of if/else statements looking at 
what STEP-## is passed into it.  From there it runs different functions.
*/
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-0","data":mergedDoc}));
mergedDoc = ouput[0]
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-1","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-2","data":mergedDoc}));
output.push(yield context.df.callActivity("E1_SayHello", {"step":"STEP-3","data":mergedDoc}));
return output;});
Ad Astra
  • 75
  • 1
  • 7