I have a Azure Function (node.js) and a list of exact times (7:30, 8:05, etc.) in a database table. I would like to trigger the Azure Function at exact times using the database table.
Now my problems are
does timer trigger only take a single cron schedule?
can I maybe use environment variables to trigger at time1 (e.g. 7:30) then when it is done, change the environment variable to time2 (e.g. 8:05) in the code? So that it would run again at time2 (8:05)?
Can a different function (HTTP triggered) run my original function (timer triggered) and also change the environment variable?
You could also use Durable Functions for this: https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-timers#usage-for-delay
There you can dynamically load the times from your database and create a new timer for the next execution. Once that one ran, create the next timer.
Basically you'll end up with an eternal orchestrator (which is ok): https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-eternal-orchestrations#periodic-work-example
does timer trigger only take a single cron schedule?
Yes, timer trigger could have only one cron expression
About dynamically cron expression, you could refer to this Configuration, the ScheduleExpression alows the setting in app settings. You could set with "schedule": "%TriggerSchedule%".And define TriggerSchedule in your appsettings. Then modify your appsettings dynamically.
The other way is use the Kudu API to modify the function.json.
PUT https://{functionAppName}.scm.azurewebsites.net/api/vfs/{pathToFunction.json}, Headers: If-Match: "*", Body: new function.json content
Then sync the function trigger.
POST https://{functionAppName}.scm.azurewebsites.net/api/functions/synctriggers
Can a different function (HTTP triggered) run my original function
(timer triggered) and also change the environment variable?
You could invoke a HTTP trigger function in a Timer function, however the Azure Functions runtime configuration file is not writable. But as it runs App Service, you can manage those settings programmatically via PowerShell, REST api, or through the CLI.
Keep in mind that changes to those settings will trigger a site restart
Related
I currently have a Node.JS server set up that is able to read and write data from a FireBase database when a request is made from a user.
I would like to implement time based events that result in an action being performed at a certain date or time. The key thing here though, is that I want to have the freedom to do this in seconds (for example, write a message to console after 30 seconds have passed, or on Friday the 13th at 11:30am).
A way to do this would be to store the date/time an action needs be performed in the database, and read from the database every second and compare the current date/time with events stored so we know if an action needs to be performed at this moment. As you can imagine though, this would be a lot of unnecessary calls to the database and really feels like a poor way to implement this system.
Is there a way I can stay synced with the database without having to call every second? Perhaps I could then store a version of the events table locally and update this when a change is made to the database? Would that be a better idea? Is there another solution I am missing?
Any advice would be greatly appreciated, thanks!
EDIT:
How I currently initialise the database:
firebase.initializeApp(firebaseConfig);
var database = firebase.database();
How I then get data from the database:
await database.ref('/').once('value', function(snapshot){
snapshot.forEach(function(childSnapshot){
if(childSnapshot.key === userName){
userPreferences = childSnapshot.val().UserPreferences;
}
})
});
The Firebase once() API reads the data from the database once, and then stops observing it.
If you instead us the on() API, it will continue observing the database after getting the initial value - and call your code whenever the database changes.
It sounds like you're looking to develop an application for scheduling. If that's the case you should check out node-schedule.
Node Schedule is a flexible cron-like and not-cron-like job scheduler
for Node.js. It allows you to schedule jobs (arbitrary functions) for
execution at specific dates, with optional recurrence rules. It only
uses a single timer at any given time (rather than reevaluating
upcoming jobs every second/minute).
You then can use the database to keep a "state" of the application so on start-up of the application you read all the upcoming jobs that will be expected and load them into node-schedule and let node-schedule do the rest.
The Google Cloud solution for scheduling a single item of future work is Cloud Tasks. Firebase is part of Google Cloud, so this is the most natural product to use. You can use this to avoid polling the database by simply specifying exactly when some Cloud Function should run to do the work you want.
I've written a blog post that demonstrates how to set up a Cloud Task to call a Cloud Functions to delete a document in Firestore with an exact TTL.
Is there any way to terminate the EC-2 instance after a particular time like 2 hours from the time of creation.
I am using NodeJS to perform the operations on AWS EC-2.
Is there any parameter I have to pass when I create the instance or I need to create a separate function for this method like some built-in method for auto-terminating the EC-2 instance.
Thanks in advance!
You can achieve this using AWS Lambda anonymous functions. You can have Lambda create your EC2 instance, and then have it delete it 2 hours later through use of a 'step function'. More info here: AWS Step Functions
The easiest method would be to have the instance terminate itself.
Upon startup, it can run a simple script like:
sleep 7200
sudo shutdown -h
To have the instance terminate on the sudo shutdown command, set the Shutdown Behavior (when the instance is launched) to Terminate.
This script could be triggered from a User Data script when the instance is started. Run the script in the background, such as:
./shutdown_script &
The benefit of doing it this way is that the instance is responsible for turning itself off. Any other option would require a timer to be set somewhere (eg Amazon CloudWatch Events), which starts to get more tricky.
I developed my Azure function app locally using VScode and pushed it to azure cloud, I have eventhub-trigger functions, I used to debug my code locally through VScode normally, but now when I run func host start --debuge, functions in my app started but nothing is triggered, I can see them triggered on the cloud through their log, it drive me mad, why they are not triggered locally, they are enabled, I restarted my function app several times, but I got nothing.
My app is https://butterflyfnapp.azurewebsites.net
In additional to Mikhail, other option is to create a separate consumer group of the Event Hub for each environment such as a cloud and development/VS and configured them in the Application settings or local.settings.json.
Then add the ConsumerGroup = "%consumergroup%" to the EventHubTrigger argument in your function, where the consumergroup is an example of the variable name in the settings.
Beside the above options, still you have a capability for testing a non-Http trigger function locally using a Http POST request. In other words, your function can be tested locally the same way like is done in the portal. More details here.
The following is an example of the testing EventHubTrigger function using a Http POST request:
url: http://localhost:7071/admin/functions/MyFunction
payload:
{
"input": '{"Id":1234,"Name":"abcd"}'
}
Event Hub consumer information (checkpoints) are stored in Blob Storage. If you share the connection string to Blob Storage between development / production environments, they will use the same checkpoints, so they will compete against each other.
My guess is that your cloud deployment always processes the events, updates the checkpoint to the latest position, and then local deployment takes this checkpoint and doesn't do anything.
To make sure this doesn't happen, create an additional "dev" Blob Storage and set the local connection string setting to that storage.
This may not actually be an issue with Identity Server or the oidc-client, but I am having trouble pinning down the problem. I am running this through System.js in an Aurelia application, so it's possible the issue originates from one of these external libraries.
In CheckSessionIFrame.start(session_state), we have the following code:
this._timer = window.setInterval(() => {
this._frame.contentWindow.postMessage(this._client_id + " " + this._session_state, this._frame_origin);
}, this._interval);
The first time the interval fires, there appear to be no problems. The iFrame's contentWindow exists (as expected) and the postMessage method is called without issue. Two seconds later, when the interval fires again, this._frame.contentWindow is undefined - so my best guess is the iFrame is dying somehow. Again, this may not be an issue with oidc-client, but I'm looking for any helpful guidance on what could cause this iFrame to die (perhaps internally it could be dying on a script?) such as a missing necessary config value for oidc-client.
For oidc-client to work with silent renew, you need to have your aurelia-app on an element that is not the body, so you can place elements within the body yet outside of your aurelia-app.
This allows you to put the IFrame outside of the aurelia-app, which prevents the Aurelia bootstrapper from eating it and lets oidc-client function independently of Aurelia.
EDIT
Based on your comment, and a little memory refreshing on my part, I rephrase/clarify:
The session checker and the silent renew functions work independently of each other. You can silent renew before the session checker has started with a manual call. You can also start the session checker without doing any silent renew. They are just convenient to use together, but that's their only relationship.
I'm assuming you use the hybrid flow and have the standard session checker implementation with an RP and OP iframe, where the OP iframe is in a check_session.html page and the RP iframe is somewhere in your aurelia app. In one of my projects I have the RP iframe in the index.html, outside of the aurelia-app element so it works independently of aurelia. But I guess it doesn't necessarily have to be there.
The session checker starts when you set the src property of the RP iframe to the location of your check_session.html with the session_state, check_session_iframe and client_id after the hash.
The check_session.html page will respond to that by starting the periodic polling and post a message back to the window of your aurelia app if the state has changed.
From your aurelia app, you listen to that message and do the signinSilent() call if it indicates a changed state. And from the silent_renew.html page, you respond to that with signinSilentCallback()
All that being in place, it really doesn't matter when you start the session checker. Tuck it away in a feature somewhere and load that feature last.
The only two things you need to worry about during the startup of your application is:
Check for window.hash starting with #code and call signinRedirectCallback(code) if it does
If it does not, just call signinSilent() right away (that leaves you with the least amount of things to check)
And then after either of those have been done, do getUser() and check if it's null or if the expired property === true. If either of those is the case, do the signinRedirect(). If not, your user is authenticated and you can let the aurelia app do it's thing and start the session checker etc.
I would definitely not put the initial authentication checks on your index.html within the aurelia-app. Because if aurelia happens to finish loading before the oidc checks are done, the process will fail. You also probably want to store the user object (and UserManager) in some cache/service/other type of singleton class so you can easily interact with oidc from your aurelia application.
I have 40 or more timer in my Node script (a timer for per connection) to count time and call a function when it's finished.
For another job, i want call a function at 23:59; so i have two solution:
Use another Java script timer to check time and call my function at 23:59.
Use Linux schedule to emit an event at 23:59.
Which is more logical? Is there another solution?
Take a look at node-cron module, I've used this to schedule recurring tasks on Node apps before:
Node Cron