Keeping Oracle Serverless Functions warm with a poor man’s Cron
What you should know: I am currently working for Oracle as Principal Cloud Architect, but any posts on this blog reflect my own views and opinions only.
Oracle Functions suffer from one of the minor issues of having a container based platform that will spin down the container after some time of running idle. The next time the function is called, the container will be spun up again, taking some seconds time to do so. This is absolutely fine if you do not rely on the function being available immediately for some synchronous transaction, e.g. if used in frontends accessed by users. One common approach to keep a function “warm” is to have a time-based trigger calling the function every few minutes.
Now in OCI there are several ways to call a serverless function, but none of them is time-based. There are quite a few other scenarios that would benefit from having a mechanism to trigger them. In this post I will explore one approach using OCI network health checks to call a function.
For the following discussion, i assume that you already have an Oracle Function at hand that you want to be called using HTTP GET or HEAD methods. As well i assume that you already have an API Gateway created with a valid deployment to call the function from public internet.
For my examples i will use abcd123456efgh.apigateway.eu-frankfurt-1.oci.customer-oci.com as endpoint hostname and /check as path prefix for the deployment.
OCI Health Checks
One important thing to understand is that the health checks are executed from outside the Oracle network, usually the probing server is hosted on another cloud providers network. This of course is necessary to perform the job the health checks are actually designed for – checking if your environment is reachable from an outside location. For our purpose this is not ideal, as we need to grant access to the api gateway from an unknown public ip.
I chose to put the api gateway only in a tiny /29 public subnet and open ports 80 and 443 in the security list. Thus no other hosts will be exposed.
For the health check to work as time trigger for calling a function we have to choose a location where the probing server will be hosted. Oracle calls this a vantage point.
If we do not pick one location ourself, OCI will use 3 default locations – which would result to our function being called multiple times. I want to avoid that to minimize simultanous function calls – this is especially important if used as a trigger for some action.
You can find a sample of a list of these vantage points in the Oracle documentation.
But honestly speaking, the list really changes a lot. Best thing to do is to run this command to fetch the list of vantage points available to you and pick one thats close to the OCI region you are using.
oci health-checks vantage-point list --query 'data[*].["display-name",geo."city-name",geo."country-name",name]' --output table
Creating the Health Check
Then you can simply create the health check using your compartment OCID, the API Gateway endpoint hostname and the path to the deployment on the API Gateway. Make sure to check if the function can be called from public internet e.g. using curl.
oci health-checks http-monitor create --compartment-id YOUR_COMPARTMENR_OCID \ --display-name "keepalive-check" --interval-in-seconds 300 \ --method HEAD --protocol "HTTPS" --timeout-in-seconds 60 \ --targets "[abcd123456efgh.apigateway.eu-frankfurt-1.oci.customer-oci.com]" --path "/check/" \ --vantage-point-names '["aws-fra"]'
That’s basically it. Now the function will be called and therefore spun up every 5 minutes.
Some things to consider when using this technique to keep your functions warm or use it as a time trigger.
- Using health checks for this purpose is some kind of dirty workaround until a proper scheduling mechanism might be available one day. So Oracle might decide anytime to block these checks somehow.
- You can only pic intervals from 10 to 900 seconds. Unless you write your own scheduler function that simply uses the wakeup-ping as ticker, this is not even a poor mans cron or scheduler. If you can live with these intervals for your use case, then you should be fine.
- Your function will be callable to everybody. You really do not want your function to trigger any tasks that are critical, produce cost or might easily be abused. So maybe keep your functions warm, do a minor data refresh or things like that.
- The call will be triggered from a vantage point, i.e. some machine on another cloud providers network. If that network or region goes down, if there is some incident leading to traffic between that cloud provider and OCI getting dropped or if the server emitting the health check probes crashes, your function will obviously not be called. This can be solved by using multiple vantage points if you do not mind your function being triggered multiple times at the same time.