faastjs
Version:
Serverless batch computing made simple.
422 lines (421 loc) • 17.4 kB
TypeScript
import { AwsOptions, AwsState } from "./aws/aws-faast";
import { CostSnapshot } from "./cost";
import { LocalOptions, LocalState } from "./local/local-faast";
import { CleanupOptions, CommonOptions, FunctionStats, Provider, ProviderImpl } from "./provider";
/**
* An array of all available provider.
* @public
*/
export declare const providers: Provider[];
/**
* `Async<T>` maps regular values to Promises and Iterators to AsyncIterators,
* If `T` is already a Promise or an AsyncIterator, it remains the same. This
* type is used to infer the return value of cloud functions from the types of
* the functions in the user's input module.
* @public
*/
export type Async<T> = T extends AsyncGenerator<infer R> ? AsyncGenerator<R> : T extends Generator<infer R> ? AsyncGenerator<R> : T extends Promise<infer R> ? Promise<R> : Promise<T>;
/**
* `AsyncDetail<T>` is similar to {@link Async} except it maps retun values R to
* `Detail<R>`, which is the return value with additional information about each
* cloud function invocation.
* @public
*/
export type AsyncDetail<T> = T extends AsyncGenerator<infer R> ? AsyncGenerator<Detail<R>> : T extends Generator<infer R> ? AsyncGenerator<Detail<R>> : T extends Promise<infer R> ? Promise<Detail<R>> : Promise<Detail<T>>;
/**
* `ProxyModule<M>` is the type of {@link FaastModule.functions}.
* @remarks
* `ProxyModule<M>` maps an imported module's functions to promise-returning or
* async-iteratable versions of those functions. Non-function exports of the
* module are omitted. When invoked, the functions in a `ProxyModule` invoke a
* remote cloud function.
* @public
*/
export type ProxyModule<M> = {
[K in keyof M]: M[K] extends (...args: infer A) => infer R ? (...args: A) => Async<R> : never;
};
/**
* Similar to {@link ProxyModule} except each function returns a {@link Detail}
* object.
* @remarks
* See {@link FaastModule.functionsDetail}.
* @public
*/
export type ProxyModuleDetail<M> = {
[K in keyof M]: M[K] extends (...args: infer A) => infer R ? (...args: A) => AsyncDetail<R> : never;
};
/**
* A function return value with additional detailed information.
* @public
*/
export interface Detail<R> {
/**
* A Promise for the function's return value.
*/
value: R;
/**
* The URL of the logs for the specific execution of this function call.
* @remarks
* This is different from the general logUrl from
* {@link FaastModule.logUrl}, which provides a link to the logs for all
* invocations of all functions within that module. Whereas this logUrl is
* only for this specific invocation.
*/
logUrl?: string;
/**
* If available, the provider-specific execution identifier for this
* invocation.
* @remarks
* This ID may be added to the log entries for this invocation by the cloud
* provider.
*/
executionId?: string;
/**
* If available, the provider-specific instance identifier for this
* invocation.
* @remarks
* This ID refers to the specific container or VM used to execute this
* function invocation. The instance may be reused across multiple
* invocations.
*/
instanceId?: string;
}
/**
* Summarize statistics about cloud function invocations.
* @public
*/
export declare class FunctionStatsEvent {
/** The name of the cloud function the statistics are about. */
readonly fn: string;
/** See {@link FunctionStats}. */
readonly stats: FunctionStats;
/**
* @internal
*/
constructor(
/** The name of the cloud function the statistics are about. */
fn: string,
/** See {@link FunctionStats}. */
stats: FunctionStats);
/**
* Returns a string summarizing the statistics event.
* @remarks
* The string includes number of completed calls, errors, and retries, and
* the mean execution time for the calls that completed within the last time
* interval (1s).
*/
toString(): string;
}
/**
* The main interface for invoking, cleaning up, and managing faast.js cloud
* functions. Returned by {@link faast}.
* @public
*/
export interface FaastModule<M extends object> {
/** See {@link Provider}. */
provider: Provider;
/**
* Each call of a cloud function creates a separate remote invocation.
* @remarks
* The module passed into {@link faast} or its provider-specific variants
* ({@link faastAws} and {@link faastLocal}) is mapped
* to a {@link ProxyModule} version of the module, which performs the
* following mapping:
*
* - All function exports that are generators are mapped to async
* generators.
*
* - All function exports that return async generators are preserved as-is.
*
* - All function exports that return promises have their type signatures
* preserved as-is.
*
* - All function exports that return type T, where T is not a Promise,
* Generator, or AsyncGenerator, are mapped to functions that return
* Promise<T>. Argument types are preserved as-is.
*
* - All non-function exports are omitted in the remote module.
*
* Arguments and return values are serialized with `JSON.stringify` when
* cloud functions are called, therefore what is received on the remote side
* might not match what was sent. Faast.js attempts to detect nonsupported
* arguments on a best effort basis.
*
* If the cloud function throws an exception or rejects its promise with an
* instance of `Error`, then the function will reject with
* {@link FaastError} on the local side. If the exception or rejection
* resolves to any value that is not an instance of `Error`, the remote
* function proxy will reject with the value of
* `JSON.parse(JSON.stringify(err))`.
*
* Arguments and return values have size limitations that vary by provider
* and mode:
*
* - AWS: 256KB in queue mode, 6MB arguments and 256KB return values in https mode. See
* {@link https://docs.aws.amazon.com/lambda/latest/dg/limits.html | AWS Lambda Limits}.
*
* - Local: limited only by available memory and the limits of
* {@link https://nodejs.org/api/child_process.html#child_process_subprocess_send_message_sendhandle_options_callback | childprocess.send}.
*
* Note that payloads may be base64 encoded for some providers and therefore
* different in size than the original payload. Also, some bookkeeping data
* are passed along with arguments and contribute to the size limit.
*/
functions: ProxyModule<M>;
/**
* Similar to {@link FaastModule.functions} except each function returns a
* {@link Detail} object
* @remarks
* Advanced users of faast.js may want more information about each function
* invocation than simply the result of the function call. For example, the
* specific logUrl for each invocation, to help with detailed debugging.
* This interface provides a way to get this detailed information.
*/
functionsDetail: ProxyModuleDetail<M>;
/**
* Stop the faast.js runtime for this cloud function and clean up ephemeral
* cloud resources.
* @returns a Promise that resolves when the `FaastModule` runtime stops and
* ephemeral resources have been deleted.
* @remarks
* It is best practice to always call `cleanup` when done with a cloud
* function. A typical way to ensure this in normal execution is to use the
* `finally` construct:
*
* ```typescript
* const faastModule = await faast("aws", m);
* try {
* // Call faastModule.functions.*
* } finally {
* // Note the `await`
* await faastModule.cleanup();
* }
* ```
*
* After the cleanup promise resolves, the cloud function instance can no
* longer invoke new calls on {@link FaastModule.functions}. However, other
* methods on {@link FaastModule} are safe to call, such as
* {@link FaastModule.costSnapshot}.
*
* Cleanup also stops statistics events (See {@link FaastModule.off}).
*
* By default, cleanup will delete all ephemeral cloud resources but leave
* behind cached resources for use by future cloud functions. Deleted
* resources typically include cloud functions, queues, and queue
* subscriptions. Logs are not deleted by cleanup.
*
* Note that `cleanup` leaves behind some provider-specific resources:
*
* - AWS: Cloudwatch logs are preserved until the garbage collector in a
* future cloud function instance deletes them. The default log expiration
* time is 24h (or the value of {@link CommonOptions.retentionInDays}). In
* addition, the AWS Lambda IAM role is not deleted by cleanup. This role
* is shared across cloud function instances. Lambda layers are also not
* cleaned up immediately on AWS when {@link CommonOptions.packageJson} is
* used and {@link CommonOptions.useDependencyCaching} is true. Cached
* layers are cleaned up by garbage collection. Also see
* {@link CleanupOptions.deleteCaches}.
*
* - Local: Logs are preserved in a temporary directory on local disk.
* Garbage collection in a future cloud function instance will delete logs
* older than 24h.
*/
cleanup(options?: CleanupOptions): Promise<void>;
/**
* The URL of logs generated by this cloud function.
* @remarks
* Logs are not automatically downloaded because they cause outbound data
* transfer, which can be expensive. Also, logs may arrive at the logging
* service well after the cloud functions have completed. This log URL
* specifically filters the logs for this cloud function instance.
* Authentication is required to view cloud provider logs.
*
* The local provider returns a `file://` url pointing to a file for logs.
*/
logUrl(): string;
/**
* Register a callback for statistics events.
* @remarks
* The callback is invoked once for each cloud function that was invoked
* within the last 1s interval, with a {@link FunctionStatsEvent}
* summarizing the statistics for each function. Typical usage:
*
* ```typescript
* faastModule.on("stats", console.log);
* ```
*/
on(name: "stats", listener: (statsEvent: FunctionStatsEvent) => void): void;
/**
* Deregister a callback for statistics events.
* @remarks
* Stops the callback listener from receiving future function statistics
* events. Calling {@link FaastModule.cleanup} also turns off statistics
* events.
*/
off(name: "stats", listener: (statsEvent: FunctionStatsEvent) => void): void;
/**
* Get a near real-time cost estimate of cloud function invocations.
* @returns a Promise for a {@link CostSnapshot}.
* @remarks
* A cost snapshot provides a near real-time estimate of the costs of the
* cloud functions invoked. The cost estimate only includes the cost of
* successfully completed calls. Unsuccessful calls may lack the data
* required to provide cost information. Calls that are still in flight are
* not included in the cost snapshot. For this reason, it is typically a
* good idea to get a cost snapshot after awaiting the result of
* {@link FaastModule.cleanup}.
*
* Code example:
*
* ```typescript
* const faastModule = await faast("aws", m);
* try {
* // invoke cloud functions on faastModule.functions.*
* } finally {
* await faastModule.cleanup();
* const costSnapshot = await faastModule.costSnapshot();
* console.log(costSnapshot);
* }
* ```
*/
costSnapshot(): Promise<CostSnapshot>;
/**
* Statistics for a specific function or the entire faast.js module.
*
* @param functionName - The name of the function to retrieve statistics
* for. If the function does not exist or has not been invoked, a new
* instance of {@link FunctionStats} is returned with zero values. If
* `functionName` omitted (undefined), then aggregate statistics are
* returned that summarize all cloud functions within this faast.js module.
* @returns an snapshot of {@link FunctionStats} at a point in time.
*/
stats(functionName?: string): FunctionStats;
}
/**
* Implementation of {@link FaastModule}.
* @remarks
* `FaastModuleProxy` provides a unified developer experience for faast.js
* modules on top of provider-specific runtime APIs. Most users will not create
* `FaastModuleProxy` instances themselves; instead use {@link faast}, or
* {@link faastAws} or {@link faastLocal}.
* `FaastModuleProxy` implements the {@link FaastModule} interface, which is the
* preferred public interface for faast modules. `FaastModuleProxy` can be used
* to access provider-specific details and state, and is useful for deeper
* testing.
* @public
*/
export declare class FaastModuleProxy<M extends object, O extends CommonOptions, S> implements FaastModule<M> {
private impl;
/** @internal */
readonly state: S;
private fmodule;
private modulePath;
/** The options set for this instance, which includes default values. */
readonly options: Required<CommonOptions>;
/** The {@link Provider}, e.g. "aws". */
provider: Provider;
/** {@inheritdoc FaastModule.functions} */
functions: ProxyModule<M>;
/** {@inheritdoc FaastModule.functionsDetail} */
functionsDetail: ProxyModuleDetail<M>;
/** @internal */
private _stats;
private _cpuUsage;
private _memoryLeakDetector;
private _funnel;
private _rateLimiter?;
private _skew;
private _statsTimer?;
private _cleanupHooks;
private _initialInvocationTime;
private _callResultsPending;
private _collectorPump;
private _emitter;
/**
* Constructor
* @internal
*/
constructor(impl: ProviderImpl<O, S>,
/** @internal */
state: S, fmodule: M, modulePath: string,
/** The options set for this instance, which includes default values. */
options: Required<CommonOptions>);
/** {@inheritdoc FaastModule.cleanup} */
cleanup(userCleanupOptions?: CleanupOptions): Promise<void>;
/** {@inheritdoc FaastModule.logUrl} */
logUrl(): string;
private startStats;
private stopStats;
/** {@inheritdoc FaastModule.on} */
on(name: "stats", listener: (statsEvent: FunctionStatsEvent) => void): void;
/** {@inheritdoc FaastModule.off} */
off(name: "stats", listener: (statsEvent: FunctionStatsEvent) => void): void;
private withCancellation;
private processResponse;
private invoke;
private lookupFname;
private createCallId;
private wrapGenerator;
private clearPending;
private wrapFunction;
/** {@inheritdoc FaastModule.costSnapshot} */
costSnapshot(): Promise<CostSnapshot>;
/** {@inheritdoc FaastModule.stats} */
stats(functionName?: string): FunctionStats;
private resultCollector;
private adjustCollectorConcurrencyLevel;
}
/**
* The return type of {@link faastAws}. See {@link FaastModuleProxy}.
* @public
*/
export type AwsFaastModule<M extends object = object> = FaastModuleProxy<M, AwsOptions, AwsState>;
/**
* The return type of {@link faastLocal}. See {@link FaastModuleProxy}.
* @public
*/
export type LocalFaastModule<M extends object = object> = FaastModuleProxy<M, LocalOptions, LocalState>;
/**
* The main entry point for faast with any provider and only common options.
* @param provider - One of `"aws"` or `"local"`. See
* {@link Provider}.
* @param fmodule - A module imported with `import * as X from "Y";`. Using
* `require` also works but loses type information.
* @param options - See {@link CommonOptions}.
* @returns See {@link FaastModule}.
* @remarks
* Example of usage:
* ```typescript
* import { faast } from "faastjs";
* import * as mod from "./path/to/module";
* (async () => {
* const faastModule = await faast("aws", mod);
* try {
* const result = await faastModule.functions.func("arg");
* } finally {
* await faastModule.cleanup();
* }
* })();
* ```
* @public
*/
export declare function faast<M extends object>(provider: Provider, fmodule: M, options?: CommonOptions): Promise<FaastModule<M>>;
/**
* The main entry point for faast with AWS provider.
* @param fmodule - A module imported with `import * as X from "Y";`. Using
* `require` also works but loses type information.
* @param options - Most common options are in {@link CommonOptions}.
* Additional AWS-specific options are in {@link AwsOptions}.
* @public
*/
export declare function faastAws<M extends object>(fmodule: M, options?: AwsOptions): Promise<AwsFaastModule<M>>;
/**
* The main entry point for faast with Local provider.
* @param fmodule - A module imported with `import * as X from "Y";`. Using
* `require` also works but loses type information.
* @param options - Most common options are in {@link CommonOptions}.
* Additional Local-specific options are in {@link LocalOptions}.
* @returns a Promise for {@link LocalFaastModule}.
* @public
*/
export declare function faastLocal<M extends object>(fmodule: M, options?: LocalOptions): Promise<LocalFaastModule<M>>;