Dialogflow - Add followupEvent after a given delay - node.js

I am trying to add a series of responses inside an intent handler and set a timer of 20 minutes which will trigger(at its end) a followup event.
So here is what I've tried:
agent.add(response_1);
//...
agent.add(response_n);
setTimeout(() => {
console.log("Setting follow up event")
agent.setFollowupEvent('20_MINUTES_PASSED');
}, 1200000);
Even though the log was displayed, my function execution stopped before it. I have checked the logs and I saw the message "Function execution took 26 ms, finished with status code: 200" displayed before "Setting follow up event".
I know that each function has a 3-5 sec timeout and I understand this is why the function finished its execution, but I cannot figure out how to trigger that event after those 20 minutes...

There are two issues with this idea: Cloud functions aren't meant to run for that long, you would have to use either a real server or some scheduling service for this. However, Dialogflow doesn't let you do this anyway, webhook requests time out after a few seconds. If you haven't send a response by then the agent will tell the user that your service is unavailable. You can also not initiate a new session without the users explicit request to do so, presumably because developers would quickly abuse this for spam etc. There is thus no way to trigger an event after 20 minutes.
The closest to what you are looking for are probably push notifications, but they are very limited compared to follow up events.

Related

ServiceBusTrigger Azure function throwing TaskCanceledException while waiting API call response

We have a ServiceBusTrigger Azure Function. During the execution of an event, it will make an API call to different service. However, before the API call returns with result, if it takes longer time, the Azure Function would throw an exception with message like the following:
Exception while executing function: FunctionName One or more errors occurred. (A task was canceled.) A task was canceled.
From the multiple occurrences, this happened after the event is triggered by 100 seconds.
My question is: Is this due to timeout? If yes, why it's timing out/cancelling the task only after 100 seconds? Shouldn't the Azure Function default timeout be 5-minute?
Thanks for any answers in advance.
After more tests, it was determined the timeout/cancellation was due to the API call as a default timeout of 100 seconds. After changing to a longer timeout, the issue was resolved.

Excute script before cycling (Heroku node.js discord bot)

I'm making a discord bot and I'm trying to save data in a private server where my bot can always get access to. Now I have done the save & load function, the only problem is, when do I save? I can send the data in the channel every minute, but that will spam the channel too much. I wonder if there's a more effeicient way to do this.
That is, is it possible to detect the heroku platform is going to start cycling, so I can make the bot save the data before it starts the cycling process- is there a way heroku provides to do that? (or maybe alternatively, track the time when heroku is going to cycle)
Part of bot.js:
// backup when start
client.on('ready',()=>{
console.log(`${client.user.tag} ready!`);
client.channels.fetch(dataChannelId)
.then(channel => {
dataChannel = channel;
console.log(dataChannel.id);
dataBackup(true);
});
});
// save - when?
dataSave(mainChannel, currentQuestionAns, currentQuestionReward, currentQuestionMessage, miliheads);
There does not seem to be a way to detect exactly when cycling will happen, but:
From Heroku:
The cycling happens once every 24 hours (plus up to 216 random minutes, to prevent every dyno for an application from restarting at the same time).
In addition, dynos are restarted as needed for the overall health of the system and your app. For example, the dyno manager occasionally detects a fault in the underlying hardware and needs to move your dyno to a new physical location.
Therefore, theoretically, a Dyno should have around 24 hours before cycling, meaning you could schedule your cleanup scripts to be run after about 24 hours:
setTimeout(() => {
dataSave(mainChannel, currentQuestionAns, currentQuestionReward, currentQuestionMessage, miliheads);
}, 24 * 55 * 60 * 1000); // 24 hours - 5 minutes
However, if the dyno restarts before this 24 hour period (due to hardware issues, or an error in your code), you may lose data. If you want to avoid this, you can save more often, such as every minute, or every time the values change, and accept the spam.
You can also programmatically force the dyno to restart using the Heroku v3 API. This can be used after you backup your data to ensure your bot restarts using the latest data. Restarting this way also resets the 24 hour counter:
// example uses got, but any HTTP request package should also work
got.delete({
url: `https://api.heroku.com/apps/${appName}/dynos`,
headers: {
"Content-Type": "application/json",
"Accept": "application/vnd.heroku+json; version=3",
"Authorization": `Bearer ${token}`
}
});
Since it seems like you are using discord messages to back up your data, but the amount of times you save it doesn't seem to matter, you can also try editing the message(s), rather than sending new messages each time you make a backup.
function dataSave(/* ... */) {
const backupMessage = await mainChannel.messages.fetch("id of a message sent by your bot");
backupMessage.edit(/* ... */);
}
Another idea for saving your data would be to use a cloud database, such as firebase or something similar.

Azure Function with Event Grid Trigger is getting called twice whereas it is being published only once from other azure function

I have an Azure Function which has Event Grid Trigger. The publish to the event grid topic to which it has been subscribed to ( manually) is being done from another azure function.
When I running the azure function with code to publish to the function with event grid trigger, the below code gets executed once as I can see from the logger which displays "Publishing to event grid" only once as expected.
log.Info("Publishing to event grid");
client.PublishEventsAsync(topicHostname,GetEventsList(id).GetAwaiter().GetResult);
However, the function with Event Grid Trigger is getting called twice as I can see the below line printed twice in the azure function with event grid trigger
2019-09-27T14:43:16.130 [Info] Function started
(Id=dc1ed52a-016b-4b25-8ebf-ac533c3ea84b)
While the execution of the function is in progress, it again displays the below line:
2019-09-27T14:43:16.168 [Info] Function started
(Id=61edb64e-f6ed-4956-851f-59e16fb1dc4e)
My expectation is that "Function started" should come in the logs only once and not twice since the other function is doing publish to the event grid topic only once. What can be a solution to make sure that the function with event grid trigger is called only once?
Thank You
My guess is that you’re hitting the event grid retry policies. Event Grid will automatically by default retry messages it thinks have failed in processing. By default it waits 30 seconds for a response from the web hook, and if more than 30 seconds has passed it assumes it failed and may retry. My assumption is that when you see it fire the second time, 30 seconds has elapsed and event grid is retrying the message. The workaround for longer running functions is to have a queue in the middle. Either Event Grid drops into a queue which functions triggers on, or the function triggers and drops in a queue (or kicks of a Durable Function Async orchestration) so that Event Grid gets an immediate “I got it” response while work continues in the background.

Azure Function calls itself after 3 minutes

i have the following code in my azure function with 5 minutes manual timeout.
when i run the above function in azure, i see the function creates a new instance after 3 minutes.(check the below image)
both the instances completes successfully ,but returns Status: 504 Gateway Timeout which in turn fails my function execution.
i have hosted the function in App Service Plan, and also increased the timeout in host.json file to 10 minutes
"functionTimeout": "00:10:00"
Several questions in here:
Timeouts - The function timeout in host.json applies to the underlying function runtime; not the http pipeline. You should not have an http function running longer than a minute. The http calls will timeout independently of the runtime (as you see with the 504). However, you could use that timeout for a long-running (ie, 60 minute on appservice plan) queue trigger. If you need a long-running function, the http call could queue a message for a queue trigger, or you could use the Durable Function support.
Why is it invoking again? The simplest interpretation here is that your function is just receiving a second http request message. Do you have evidence that's not the case? You could bind to the HttpRequestMessage and log additional http request properties to track this down.

Azure Function on Always-On App Service Plan Times Out with No functionTimeout Set

Like the title describes - I have an Azure Function on the App Service Plan, configured for Always On and no functionTimeout set in my host.json, and it appears to timeout / not finish anytime after 30 minutes to 1 hour.(...but I feel this may be a false positive...)
The HTTP Triggered function can sometimes take over 1-2 hours to complete. I understand that this probably isn't the best design and according to the Azure Function Best Practices I should break this out into smaller / more manageable pieces - I get that. However, I expect the Function on the App Service plan to work as advertised - no hard limit on execution time. Perhaps this is the same question as Unexpected azure-function timeouts on app-service-plan, but that has no answer and I am using an HTTP Trigger instead.
Currently, the HTTP Triggered method does not return until the work is complete. (Is this a problem - the HTTP trigger needs to return quicker?)
According to the Kudu Function Invocation Logs, this case reports "Never Finished", and when I click on the Toggle Output button to view the logs, they never come in.
When I viewed this function's run in the Logs section of that trigger, it seems like the function just stopped, and the log stream just reports no new trace:
2017-07-26T16:36:43.116 [INFO] [Class1] Update operation started processing 790 sales records ...
2017-07-26T16:36:43.116 [DBUG] [Class2] Matching and updating ids from the map...
2017-07-26T16:38:07 No new trace in the past 1 min(s).
2017-07-26T16:39:07 No new trace in the past 2 min(s).
2017-07-26T16:40:07 No new trace in the past 3 min(s).
2017-07-26T16:41:07 No new trace in the past 4 min(s).
So not sure why this function just seemed to stop - or perhaps it stopped collecting log statements (there are many), and for some reason, the function never completed.
Any ideas?
Approx time: 2017-07-26T16:00:00 UTC
InvocationID: d856c107-f1ee-455a-892b-ed970dcad128 (I think?)
If it is indeed being timed out, is there any way for us to know, (Exception? App Insights? etc.)
Based on my test, I found azure function will not stop your function if you don't set the timeout.
Here is my test, I create a ManualTrigger function which will log the message every 10 minutes.
The codes like below:
public static void Run(string input, TraceWriter log)
{
for (int i = 0; i < 100; i++)
{
log.Info( "Worked " + i*10 + " minutes ");
Thread.Sleep(600000);
}
}
The log details:
In the log, you could find my function executed 70 minutes.It still works well.
The no trace means there are no new requests send to the azure function.
Currently, the HTTP Triggered method does not return until the work is complete. (Is this a problem - the HTTP trigger needs to return quicker?)
As Jesse Carter says, you couldn't execute long time function when you used HTTP Triggered method.
Since your client-side(send request) will have a timeout value. It will wait for the function's response.
Normally, if we want to execute long time function, I suggest you could use http trigger to get the request. In the http trigger function you could add a queue message to the azure storage queue.
Then you could write a queue trigger function which will execute the long time work.
If your HTTP method takes more than a minute, you should be offloading it to a Queue. Period. (I know the other answers have said this, but it's worth repeating).
Http connections are a limited resource.
While Azure Functions as an execution engine can handle long running
operations (as demonstrated by queue / service bus support), the
http pipeline may cut off / timeout long running requests.
Queue triggers can easily run for 30+ minutes. If your job is longer than that, you really should split it into multiple queue messages.
Also check out Durable Function support: https://github.com/Azure/azure-functions-durable-extension/
Regardless of the function app timeout setting, 230 seconds is the maximum amount of time that an HTTP triggered function can take to respond to a request. This is because of the default idle timeout of Azure Load Balancer. For longer processing times, consider using the Durable Functions async pattern or defer the actual work and return an immediate response.
Function app timeout duration: Check Notes

Resources