Skip to main content

ScheduledFunction

Hypi's ScheduledFunction helps to schedule a function to run automatically. User Defined Functions or Serverless Functions can be automated to run at a particular time or on a recurring basis.

ScheduledFunction data type manages the execution of scheduled functions. Let's look at the structure of this type.

type ScheduledFunction {
fn: GraphQLRef!
schedule: Schedule
id: String
arcql: String
type: String!
}

type Schedule {
start: DateTime!
end: DateTime
repeats: Boolean!
interval: ScheduledInterval!
intervalFrequency: Int
intervalFrequencySubset: String
intervalDay: Int
intervalHour: Int
lastExecuted: DateTime
lastExecutionStarted: DateTime
nextExecution: DateTime
consecutiveFailures: Int
lastExecutionSucceeded: Boolean
lastExecutionError: String
}

ParameterDescriptionExample
fnThis refers to a GraphQL function to be scheduled to runfn has subfields like type and field. The type can be Query/Mutation/ Subscription. field is the name of the function to be scheduled for execution.
idThis is the ID of the object on which the function should operate. This is an optional field, required IFF arcql is provided.hypi.id of the object to work on
arcqlThis is an arcql statement. On execution, this provides the scheduled function with the data to operate. This is an optional field, required IFF id is provided.Any ArcQL statement
typeThe type on which the scheduled function should operate. The ID parameter if provided is the ID of an object of this type.Data type
startStart date and time to runShould have valid ISO 8601 DateTime value
endEnd date and timeShould have valid ISO 8601 DateTime value
repeatsSet to true to repeat the executiontrue / false
intervalThe interval to repeat the execution. Interval could be per minute, per hour, per week, per month, at the start of the month, at the end of the month, throughout the year, at the start of the year, or the end of the yearMINUTE / HOUR /DAY / WEEK / MONTH / MONTH_START/ MONTH_END / YEAR / YEAR_START/ YEAR_END
intervalFrequencyThis is a multiplier for the interval.Defaults to 1. If the intervalFrequency is 1 and interval is MINUTE, the function is executed once per minute. If it is 2 and the interval is WEEK, the function is executed every 2 WEEKS.
intervalFrequencySubsetThis is a comma-separated list of numbers representing the frequency at which the function is executed. These values are a subset of the selected interval.If the interval is MONTH, then the subset has a possible range of 1 to 12. Values 1,2,6,12 would mean executing this function every January, February, June, and December until the end date. If the interval is DAY, the possible range will be 1 to 7. Values 1,3,7 would mean executing this function every Sunday, Tues and Saturday.
intervalDayIf the interval is MONTH this specifies which day of the month. If null, it defaults to the beginning of the Month.Value 13 means execute on the 13th day of every month.
intervalHourIf the interval is bigger than HOUR then this specifies the hour/time of execution. Defaults to midnight i.e. 0.If the interval is DAY, this sets which hour of the day to execute.
lastExecutedDate and time of executionAutomatically set by the system
lastExecutionStartedDate and time of the start of the execution.Automatically set by the system
nextExecutionDate and time of next executionAutomatically set by the system
lastExecutionSucceededStatus of last executionUpdated to true if last execution was successful
lastExecutionErrorError message if execution failedAutomatically updated by the system

Example 1

Let's run below node-js serverless example function every Minute.

/**
* @param input has env and args
* @param callback accepts two params, 1st one is the response to return and second is error if there is one
*/
function hellWorld(input, callback) {
console.log('Yeah, we got some input', input, input.env, input.args);
callback(input, null);
}

// Must export `main`
exports.main = hellWorld;

Detailed instructions are given in this README file on how to deploy and execute serverless functions.

You may also follow below steps to deploy node-js serverless function.

First, authenticate Docker with Hypi Container Registry by login. Use Authorization token from developer console as password.

docker login hcr.hypi.app -u hypi

To build the docker image, use the following command.

docker build --platform=linux/amd6 . -t hcr.hypi.app/node-js:v1

--platform=linux/amd6 parameter is applicable while using a platform other than linux. This means you can run this command on windows and Mac (including M1 chips).

Now let’s deploy the serverless function on Hypi’s low code backend

docker push hcr.hypi.app/node-js:v1

Add the below serverless function in the schema editor.

type Query {
myNodeJSFn(id: String, arcql: String, type: String!): Json @fn(name:"node-js", version: "v1")
}

Please note that input parameters must be exactly as given above.

Our serverless function is ready to use! Let's execute it to run every Minute.

mutation {
upsert(
values: {
ScheduledFunction: [
{
hypi: { id: "f1" }
schedule: {
hypi:{id:"s1"}
start: "2024-02-27T12:10:37Z"
end: "2024-02-29T20:00:00Z"
interval: MINUTE
intervalFrequency: 1
repeats: true
}
id: "p1"
type: "Pair"
fn: { type: Query, field: "myNodeJSFn" }
}
]
}
) {
id
}
}

Let's check the ScheduledFunction data type for the status of execution of the function.

{
find(type: ScheduledFunction, arcql: "*") {
edges {
node {
... on ScheduledFunction {
fn {
type
field
}
nextExecution
lastExecuted
lastExecutionSucceeded
lastExecutionError
}
}
cursor
}
}
}

Example 2

Let's run the below testSchedule function every Minute. Define the function in the schema editor. It creates an object of type Pair with key and value fields.

type Mutation {
testSchedule(id: String, arcql: String, type: String!): Json @tan(type: Groovy, inline:
"""return upsert([
Pair: [
[
key : "A",
value : "B",
hypi: [
id : id
]
]
]
]
)
"""
)
}

Use upsert to schedule the function.

We are going to execute it every minute. So, interval is MINUTE and intervalFrequency is 1 as it creates an object p1 with key-value pair. Remember to put start time in UTC format as it is a required field.

mutation {
upsert(
values: {
ScheduledFunction: [
{
start: "2022-06-08T12:10:37Z"
interval: MINUTE
intervalFrequency: 1
id: "p1"
type: "Pair"
repeats: true
fn: { type: Mutation, field: "testSchedule" }
}
]
}
) {
id
}
}

So, our scheduled function got registered to run!

Let's check if the Pair object got created to check the execution of the testSchedule function.

{
find(type: Pair, arcql: "*") {
edges {
node {
... on Pair {
key
value
}
}
cursor
}
}
}

Example 3

Define the below function in the schema editor. It finds title and price from Book objects and saves a record in the Counter object.

type Mutation {
testSchedule1(id: String, arcql: String, type: String!): Json @tan(type: Groovy, inline: """
def matches = gql(\""" {
find(type: Book, arcql: "$arcql") {
edges {
node {
... on Book {
title
price
}
}
}
}
}
\""").data.find.edges
return upsert([
Counter: [
[
name : "Counter1",
label : matches[0].node.title,
value : matches[0].node.price,
hypi: [
id : id,
]
]
]
]
)
""")
}

Use upsert to schedule the function.

We are going to execute it every two hours. So, interval is HOUR and intervalFrequency is 2 . It creates an object Book1 of the Counter data type by processing the arcql filter on the Book data type.

mutation {
upsert(
values: {
ScheduledFunction: [
{
start: "2022-06-08T12:10:37Z"
interval: HOUR
intervalFrequency: 2
id: "Book1"
type: "Book"
arcql: "price > 12"
repeats: true
fn: { type: Mutation, field: "testSchedule1" }
}
]
}
) {
id
}
}

Let's check the ScheduledFunction data type for the status of execution of the function.

{
find(type: ScheduledFunction, arcql: "*") {
edges {
node {
... on ScheduledFunction {
fn {
type
field
}
nextExecution
lastExecuted
lastExecutionSucceeded
lastExecutionError
}
}
cursor
}
}
}

And the Book1 object got created!

{
"data": {
"find": {
"edges": [
{
"node": {
"hypi": {
"id": "Book1"
},
"name": "Counter1",
"label": "PQR",
"value": 13.99
},
"cursor": "Book1"
}
]
}
}
}