Change Value in Firebase At Specific Time [duplicate] - c#

I am looking for a way to schedule Cloud Functions for Firebase or in other words trigger them on a specific time.

Update 2019-04-18
There is now a very simple way to deploy scheduled code on Cloud Functions through Firebase.
You can either use a simple text syntax:
export scheduledFunctionPlainEnglish =
functions.pubsub.schedule('every 5 minutes').onRun((context) => {
console.log('This will be run every 5 minutes!');
})
Or the more flexible cron table format:
export scheduledFunctionCrontab =
functions.pubsub.schedule('5 11 * * *').onRun((context) => {
console.log('This will be run every day at 11:05 AM UTC!');
});
To learn more about this, see:
The Scheduling Cloud Functions for Firebase blog post introducing the feature.
The documentation on scheduled functions.
Note that your project needs to be on a Blaze plan for this to work, so I'm leaving the alternative options below for reference.
If you want to schedule a single invocation of a Cloud Function on a delay from within the execution of another trigger, you can use Cloud Tasks to set that up. Read this article for an extended example of how that can work.
Original answer below...
There is no built-in runat/cron type trigger yet.
For the moment, the best option is to use an external service to trigger a HTTP function periodically. See this sample in the functions-samples repo for more information. Or use the recently introduced Google Cloud Scheduler to trigger Cloud Functions through PubSub or HTTPS:
I also highly recommend reading this post on the Firebase blog: How to Schedule (Cron) Jobs with Cloud Functions for Firebase and this video: Timing Cloud Functions for Firebase using an HTTP Trigger and Cron.
That last link uses cron-job.org to trigger Cloud Functions, and works for projects that are on a free plan. Note that this allows anyone to call your function without authorization, so you may want to include some abuse protection mechanism in the code itself.

What you can do, is spin up an AppEngine instance that is triggered by cron job and emits to PubSub. I wrote a blog post specifically on that, you might want to take a look:
https://mhaligowski.github.io/blog/2017/05/25/scheduled-cloud-function-execution.html

It is important to first note that the default timezone your functions will execute on is America/Los_Angeles according to the documentation. You may find a list of timezones here if you'd like to trigger your function(s) on a different timezone.
NB!!: Here's a useful website to assist with cron table formats (I found it pretty useful)
Here's how you'd go about it:
(Assuming you'd like to use Africa/Johannesburg as your timezone)
export const executeFunction = functions.pubsub.schedule("10 23 * * *")
.timeZone('Africa/Johannesburg').onRun(() => {
console.log("successfully executed at 23:10 Johannesburg Time!!");
});
Otherwise if you'd rather stick to the default:
export const executeFunction = functions.pubsub.schedule("10 23 * * *")
.onRun(() => {
console.log("successfully executed at 23:10 Los Angeles Time!!");
});

Related

Azure Functions: timer trigger and consumption plan issue

In my dev environment, I have an Azure Functions with 21 functions and the app plan is consumption.
Some functions have a timer trigger and at the end of the process each function sends an email. I have 2 type of timer trigger:
run a function every 20 minutes
run a function once at a particular time in the night
Every 20 minutes the function is doing what I expect. Great.
The problem I'm facing is with the function that they have to start at a particular time. Basically, they don't start until I open the portal and do something on the Azure Function (for example open the monitor for one of them).
In the code point of view, all functions with the timer trigger are defined like that:
[FunctionName("invoiceMonthlyGeneratorTimer")]
public void Run([TimerTrigger("%Timers:GenerateMonthlyInvoices%")] TimerInfo myTimer)
{
// ..
}
[FunctionName("invoiceDunningTimer")]
public async Task Run([TimerTrigger("%Timers:DunningTimer%")] TimerInfo timer)
{
// ...
}
The configuration of the timer is in the settings file like:
"Timers": {
"DunningTimer": "0 0 4 * * *",
"GenerateMonthlyInvoices": "0 0 4 * * *"
}
Generally, speaking, this approach was working in dev environment and it is working perfectly in the production environment.
Because each function sends an email, I expect each morning to find in my inbox some emails but it doesn't happen. Then, I open the Azure portal to see the logs and the monitor.
Open the Azure function in the portal.
Open the monitor for a function
Voila, after a couple of seconds, I start to receive the email for all services! In the production environment I don't have all the function I have in dev because I want to test before deploying. In prod the functions are working fine and start at the right time.
If I look at Application Insights, I can find only the logs for the time I opened the monitor.
There is one interesting thing in the log:
Trigger Details: UnscheduledInvocationReason: IsPastDue, OriginalSchedule: 2020-07-24T05:00:00.0000000+00:00
Update
Apparently, you can't have more than a couple of timer triggers in the same Azure Functions. I opened an issue on Github, so if other devs are facing the same. Something similar with HTTP triggers, look this post.
There are too many functions in your function app, they may interact each other. I met similar problem with this, in that case, the timer trigger functions in one function app and did not work. But when i deploy them to different function apps, they work fine. so you can try to deploy your second function to another function app.
And I suggest you report this problem to Microsoft, they can know more information about this problem, and may have a better solution.

Outlook get FreeBusy information is slow

My code is an MS Outlook addin and is used for creating a absence calendar for 60+ people of a team. The company uses MS Exchange.
I am retrieving their free/busy status with this code:
var namespace = ThisAddIn.thisOutlookApp?.GetNamespace( "MAPI" );
var recp = namespace.CreateRecipient( personName );
var freeBusy = recp.FreeBusy( startDate, MinPerChar: 60, CompleteFormat: true );
Although this works file, one call to FreeBusy() takes about 300 milliseconds. For 60 people and a time span of three months, this means my code takes nearly a minute.
I also tried this alternative:
recp.Resolve();
var exu = recp.AddressEntry.GetExchangeUser();
var freeBusy = exu.GetFReeBusy(...)
but no difference. The same code in VBA shows the same performance.
Is their a trick to speed up this call, or is there an alternative way to get the free/busy information, e.g. by accessing other people's calendar or by talking to the MS Exchange server itself?
Use GetUserAvailability EWS operation - it allows to request f/b info for multiple users in a single call.
I found a good solution myself:
I did not use the Outlook Interop API, but calls to the Exchange server itself using the EWS Managed API.
There is an excellent set of 101 sample projects. (It's really 101 samples!) and a very good step-by-step tutorial for getting started with the EWS Managed API.
"Exchange 2013 Get users' status setting programmatically" was the sample that I used.
However, I'm keen to hear about alternative solutions from SO users.

Azure Application Insights custom response metric

I need some help to find a good pattern for a custom application insights metric.
Environment
I have a custom Windows Service running on multiple Azure VMs.
I can successfull add Events to my Monitoring instance on Azure.
Goal
I want to create a custom metric that allows me to monitor if my windows services are running and responding per instance. It would be perfect if it acts like the respond timeout in website metric.
Each service instance has a custom maschine related identifier, like:
TelemetryClient telemetry = new TelemetryClient();
telemetry.Context.Device.Id = FingerPrint.Instance;
Now I wnat to create a alert if one of my Service instances (Context.Device.Id) is not running or responding.
Question
How to achive this?
Is it even possible or usefull to Monitor multiple instance of one service type onside on application insight? Or must I open one single application insight per instance?
Can anybody help me?
Response to Paul's answere
Track Metric Use TrackMetric to send metrics that are not attached to particular events. For example, you could monitor a queue length at regular intervals.
If I do so, whats happens if my server made a restart (update or somethink) and my service don't start up. Now the service did't send a TrackMetric to the application insight and no alert is raised because the value don't drop below 1, but the Service is still not running.
Regards Steffen
I found a good working solution, with only a few simple steps.
1) Implement a HttpListener instance on a service port (for example 8181) with a simple text response "200: OK"
2) Add a matching endpoint to the azure VM imstande
3) Create a default web test on "myVM.cloudapp.net:8181" with checkup of response text
Work great so far and matches all my needs! :)
Per the documentation on Azure portal:
https://azure.microsoft.com/en-us/documentation/articles/app-insights-api-custom-events-metrics/#track-metric
Track Metric
Use TrackMetric to send metrics that are not attached to particular events. For example, you could monitor a queue length at regular intervals.
Metrics are displayed as statistical charts in metric explorer, but unlike events, you can't search for individual occurrences in diagnostic search.
Metric values should be >= 0 to be correctly displayed.
c# code looks like this
private void Run() {
var appInsights = new TelemetryClient();
while (true) {
Thread.Sleep(60000);
appInsights.TrackMetric("Queue", queue.Length);
}
}
I don't think there is currently a good way to accomplish this. What you're actually looking for is a way to detect a "stale heartbeat." For example, if your service was sending up an event "Service Health is okay", you'd want an alert that you haven't received one of those events in a certain amount of time. There aren't any date/time conditional operators in AI's alert system.
Microsoft might explain that this scenario is not intended to be satisfied by AI, as this is more of a "health checking" system's responsibility, like SCOM or Operation Insights or something else entirely.
I agree this is something that needs a solution, and using AI for it would be wonderful (I've already attempted to accomplish the same thing with no luck); I just think "they" will say its not a scenario in the realm of responsibility for AI.

Birthdays Reminder Code for Asp.Net MVC

I want to create a web application in MVC Asp.Net for Hotel Room Booking and Customers Management. I am having trouble with one of the requirement. I want to create a code for Sending SMS to Customers on their Birthdays for Wishing them from Hotel. I am confused, that where should i place the code for checking customers with birthdate same as today's Date, so that Code gets Triggered every day at 12:00 am even if the web application is not launched. Please can you explain where should i insert the code?
There is a open-source library called Quarz which will help you with that.
There is a very good blog article by Mike Brind about this library. The library provides a fluent API which allows you to do exactly what you want.
The following code (based on the example of the mentioned blog article) creates a event which is called every day at 12 o´clock:
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
IJobDetail job = JobBuilder.Create<BirthdayJob>().Build();
ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(12, 0))
)
.Build();
scheduler.ScheduleJob(job, trigger);
It can run in the context of the Website, a Windows Service or even a WinForms-Application (as long the user doesn't closes it).
Depending on the context you need to schedule the job in different places. For a Website in would be the Application_Start()-Method. For a Service this would be the OnStart()-Method.
Additionally you need a class "BirthdayJob" which will provide the actual code which should be executed periodically:
public class BirthdayJob : IJob
{
public void Execute(IJobExecutionContext context)
{
// Check for birthdays...
}
}
There is one point you should be aware of if you call this code in the context of a website:
It's possible that the IIS puts your website to sleep if it isn't requested for a while. In this case it would be possible that the scheduled tasks are not executed.
There is an option to change the timeout for your website:
In the IIS manager go to "Application Pools", find the application pool that is used for your website and select "Properties" -> "Performance". There you can set the idle timeout. There are several other approaches to solve this problem.
However, if your website is requested frequently you would never see this problem.
The best way to go would be to call Quarz from a Windows-Service which runs even if your websites sleeps or lays down drunken under a table.
You could ship a service together with your web application which does the periodic checks and runs separately from the site.
Another usage of this service could be general maintenance of the data store which is used by the site, thus, for instance, once a day it would archive information, check birthdays and any other maintenance or periodic tasks, such as the issuing of reminders, etc. which your platform would issue.

Starting an existing Mainframe job with FTP and C#

We have a lot of jobs(jcl) running on the mainframe.
I was asked to try and start a restore job. I have to do this with a C# application.
What i got now is i am able to connect to the mainframe with an ftp library and I can call raw FTP commands that the mainframe understands.
I kind of know how to submit a .jcl file, which will be processed as a job if I use the command "quote site filetype=jes".
My questions are:
- Is there a way to start an existing job?
- Does it matter what "directory"/partition(?) I have navigated to before submitting a job?
You could submit the below JCL through FTP and it would run the JCL in JOB.LIBRARY(JOB)
//JS010 EXEC PGM=IEBGENER
//SYSUT1 DD DSN=JOB.LIBRARY(JOB),DISP=SHR
//SYSUT2 DD SYSOUT=(,INTRDR)
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
Expanding on Bills comments, is this a Production, Development, Test, QA etc job.
In production on mainframe's, jobs are normally run using a Scheduler (e.g. Ca7 or Workload Scheduler for z/OS (formerly OPC) + several others). Some sites also use Schedulers in QA / Development as well, but this is rare.
Submitting a job via a scheduler
To submit via a scheduler you MUST talk to the Operations / Production Control / Mainframe Support department. They should know what is possible and have preferred ways of doing something like this. They should also know what access is required !!!
Possible options would include:
Most schedulers have the option of submitting a job / schedule when a Dataset (File for non-mainframer's) is created. If available this will probably be the easiest to implement.
All schedulers provide programs that can submit schedules.
You may be able to run a job that submits the appropriate job
Run a program in the foreground to submit the appropriate job
These days most of the schedulers would have a Web interface, they may also have interfaces on other platform. This option is probably not going to be available though.
Submitting a job
If you are just going submit the job, options include:
Copying the job to the INTRDR as #Deuian has done (either foreground or background).
Running TSO background
Submitting via job (from Deuian's answer):
//JOBNAME JOB ...
//JS010 EXEC PGM=IEBGENER
//SYSUT1 DD DSN=JOB.LIBRARY(JOB),DISP=SHR
//SYSUT2 DD SYSOUT=(,INTRDR)
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY
Finally to do anything on the Mainframe, you will need the appropriate security access !!!
I have tried to provide a background information + a basic guide of the option available. Basically you need to talk to Mainframe-Operation / Mainframe-programmers !!!.
Yes, you can - just execute the RETR 'DATASET.NAME' FTP command. Remember that the quotes here are important - without quotes the command would be interpreted as "read spool files by JOBID". And with quotes it would be interpreted as "submit an existing JCL data set, wait for job to complete and retrieve it's spool". And it doesn't matter what directory you have navigated to before submitting a job.
You can refer to my Java implementation of JES client which works through FTP - https://github.com/vadimshchukin/jesclient. It has code which does exactly what you want:
public JESJob execute(String datasetName) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
retrieveFile(String.format("'%s'", datasetName), outputStream);
JESJob job = new JESJob(this);
job.setSpool(outputStream.toString());
return job;
}

Categories

Resources