I'm a bit late here, so sorry if I've got something wrong but it seems like the issue is needing a long running workflow. Normally, they're limited to 15mins, as you've noticed, but there is a way to pause them. Tasks.... I'm fairly sure they weren't meant for this, but I think it will work. The idea is that the majority of the time in that 15mins is actually spent waiting, so we want to move that outside of the workflow. We need to poll every 5 mins, so we don't want to use a workflow specifically for that
- although, you COULD create a workflow on a 5 min cron job and have it get a list of tasks, poll each one, if it's ready it returns the result otherwise null... I'd actually use like 4min or something cause there is a scenario where a task is posted while the cron job workflow is running causing a longer than 5min wait.
Ideally, in Retool, we'd want the frontend to poll since there are no limits there. So you would want to set up something like:
function pollPowerBI(reportId) {
console.log("Polling API");
// Add your polling code here
}
const PbiPollTimer = setInterval(function() {
// Get all incomplete tasks
// For each task
// - get the reportId
// - call pollPowerBI(reportId);
// - check response
// 1) if export isn't finished, leave the task alone and check the next one
// 2) if export is finished, complete the task sending the polling results
}, 5 * 60 * 1000);
technically, like 95% of the time this will "run" in the background.... while it's paused. when it isn't paused though, the pollPowerBI(repotId) function runs on the "main" thread (the UI). If you're worried about blocking, it shouldn't be an issue since Retool is built on React, but I recently learned you can start a Web Worker with a Data URI instead of using a .js file so you could try using this method to ensure work doesn't interrupt the UI:
let worker = new Worker(
`data:text/javascript,
function functionThatTakesLongTime(someArgument){
//There are obviously faster ways to do this, I made this function slow on purpose just for the example.
for(let i = 0; i < 1000000000; i++){
someArgument++;
}
return someArgument;
}
onmessage = function(event){ //This will be called when worker.postMessage is called in the outside code.
let foo = event.data; //Get the argument that was passed from the outside code, in this case foo.
let result = functionThatTakesLongTime(foo); //Find the result. This will take long time but it doesn't matter since it's called in the worker.
postMessage(result); //Send the result to the outside code.
};
`
);
worker.onmessage = function(event){ //Get the result from the worker. This code will be called when postMessage is called in the worker.
console.log("The result is " + event.data);
}
let foo=10;
worker.postMessage(foo);
- little note,
foo up above, can be most things except an object with methods. The solution here is dumb:
// ... all the same code as above here
let foo = myFunctionWithMethods;
foo = JSON.parse(JSON.stringify(foo));
worker.postMessage(foo)
I tested it and it ran (printing 1000000010), you'll obviously need to change it for polling but I think this will get you started (if not just yell at me lol).
I think if you set it up this way your workflow can sit and wait days for the export to complete.... the only downside is that since you've delegated polling to the frontend, you now MUST be on that page for the polling to run. so, a bit of a downside, but maybe its a better place than where you're stuck right now? hopefully? 
btw, I use polling in one of my apps (chat app actually) it polls on 30sec intervals and the UI has no issues at all. so I really don't think you'll need the Web Worker, but that'll have to be up to you since we don't know what happens after those 3 blocks 