Skip to content

Commit

Permalink
Add native support for warmup trigger (#180)
Browse files Browse the repository at this point in the history
* Add warmup trigger

* Additional changes to types

* Add back trigger property

* Minor changes to docs, types, signatures

* Revert a few minor edits

* PR review suggestions

* Add interface for warmupContext
  • Loading branch information
castrodd authored Oct 31, 2023
1 parent cc818aa commit c3aa2c4
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/addBindingName.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

export { InvocationContext } from './InvocationContext';
export { HttpRequest } from './http/HttpRequest';
export { HttpResponse } from './http/HttpResponse';
export { InvocationContext } from './InvocationContext';

const bindingCounts: Record<string, number> = {};
/**
* If the host spawns multiple workers, it expects the metadata (including binding name) to be the same accross workers
* If the host spawns multiple workers, it expects the metadata (including binding name) to be the same across workers.
* That means we need to generate binding names in a deterministic fashion, so we'll do that using a count
* There's a tiny risk users register bindings in a non-deterministic order (i.e. async race conditions), but it's okay considering the following:
* 1. We will track the count individually for each binding type. This makes the names more readable and reduces the chances a race condition will matter
Expand Down
5 changes: 5 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
StorageBlobFunctionOptions,
StorageQueueFunctionOptions,
TimerFunctionOptions,
WarmupFunctionOptions,
} from '@azure/functions';
import * as coreTypes from '@azure/functions-core';
import { CoreInvocationContext, FunctionCallback } from '@azure/functions-core';
Expand Down Expand Up @@ -145,6 +146,10 @@ export function cosmosDB(name: string, options: CosmosDBFunctionOptions): void {
generic(name, convertToGenericOptions(options, <any>trigger.cosmosDB));
}

export function warmup(name: string, options: WarmupFunctionOptions): void {
generic(name, convertToGenericOptions(options, trigger.warmup));
}

export function generic(name: string, options: GenericFunctionOptions): void {
if (!hasSetup) {
setup();
Expand Down
9 changes: 9 additions & 0 deletions src/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
StorageQueueTriggerOptions,
TimerTrigger,
TimerTriggerOptions,
WarmupTrigger,
WarmupTriggerOptions,
} from '@azure/functions';
import { addBindingName } from './addBindingName';

Expand Down Expand Up @@ -90,6 +92,13 @@ export function cosmosDB(options: CosmosDBTriggerOptions): CosmosDBTrigger {
});
}

export function warmup(options: WarmupTriggerOptions): WarmupTrigger {
return addTriggerBindingName({
...options,
type: 'warmupTrigger',
});
}

export function generic(options: GenericTriggerOptions): FunctionTrigger {
return addTriggerBindingName(options);
}
Expand Down
13 changes: 13 additions & 0 deletions types/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { HttpFunctionOptions, HttpHandler, HttpMethodFunctionOptions } from './h
import { ServiceBusQueueFunctionOptions, ServiceBusTopicFunctionOptions } from './serviceBus';
import { StorageBlobFunctionOptions, StorageQueueFunctionOptions } from './storage';
import { TimerFunctionOptions } from './timer';
import { WarmupFunctionOptions } from './warmup';

/**
* Registers an http function in your app that will be triggered by making a request to the function url
Expand Down Expand Up @@ -143,6 +144,18 @@ export function eventGrid(name: string, options: EventGridFunctionOptions): void
*/
export function cosmosDB(name: string, options: CosmosDBFunctionOptions): void;

/**
* Registers a function in your app that will be triggered when an instance is added to scale a running function app.
* The warmup trigger is only called during scale-out operations, not during restarts or other non-scale startups.
* Make sure your logic can load all required dependencies without relying on the warmup trigger.
* Lazy loading is a good pattern to achieve this goal.
* The warmup trigger isn't available to apps running on the Consumption plan.
* For more information, please see the [Azure Functions warmup trigger documentation](https://learn.microsoft.com/azure/azure-functions/functions-bindings-warmup?tabs=isolated-process&pivots=programming-language-javascript).
* @param name The name of the function. The name must be unique within your app and will mostly be used for your own tracking purposes
* @param options Configuration options describing the inputs, outputs, and handler for this function
*/
export function warmup(name: string, options: WarmupFunctionOptions): void;

/**
* Registers a generic function in your app that will be triggered based on the type specified in `options.trigger.type`
* Use this method if your desired trigger type does not already have its own method
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from './storage';
export * from './table';
export * from './timer';
export * as trigger from './trigger';
export * from './warmup';

/**
* Void if no `return` output is registered
Expand Down
6 changes: 6 additions & 0 deletions types/trigger.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
StorageQueueTriggerOptions,
} from './storage';
import { TimerTrigger, TimerTriggerOptions } from './timer';
import { WarmupTrigger, WarmupTriggerOptions } from './warmup';

/**
* [Link to docs and examples](https://docs.microsoft.com/azure/azure-functions/functions-bindings-http-webhook-trigger?&pivots=programming-language-javascript)
Expand Down Expand Up @@ -66,6 +67,11 @@ export function eventGrid(options: EventGridTriggerOptions): EventGridTrigger;
*/
export function cosmosDB(options: CosmosDBTriggerOptions): CosmosDBTrigger;

/**
* [Link to docs and examples](https://learn.microsoft.com/azure/azure-functions/functions-bindings-warmup?tabs=isolated-process&pivots=programming-language-javascript)
*/
export function warmup(options: WarmupTriggerOptions): WarmupTrigger;

/**
* A generic option that can be used for any trigger type
* Use this method if your desired trigger type does not already have its own method
Expand Down
17 changes: 17 additions & 0 deletions types/warmup.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

import { FunctionOptions, FunctionResult, FunctionTrigger } from './index';
import { InvocationContext } from './InvocationContext';

export interface WarmupContextOptions {}
export type WarmupHandler = (warmupContext: WarmupContextOptions, context: InvocationContext) => FunctionResult;

export interface WarmupFunctionOptions extends WarmupTriggerOptions, Partial<FunctionOptions> {
handler: WarmupHandler;

trigger?: WarmupTrigger;
}

export interface WarmupTriggerOptions {}
export type WarmupTrigger = FunctionTrigger & WarmupTriggerOptions;

0 comments on commit c3aa2c4

Please sign in to comment.