@google-cloud/pubsub
Version:
Cloud Pub/Sub Client Library for Node.js
516 lines (515 loc) • 17.5 kB
TypeScript
/*!
* Copyright 2018 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PreciseDate } from '@google-cloud/precise-date';
import { google } from '../protos/protos';
import { FlowControlOptions } from './lease-manager';
import { BatchOptions } from './message-queues';
import { MessageStreamOptions } from './message-stream';
import { Subscription } from './subscription';
import { SubscriberClient } from './v1';
import * as tracing from './telemetry-tracing';
import { Duration } from './temporal';
import { EventEmitter } from 'events';
export { StatusError } from './message-stream';
/**
* Loggers. Exported for unit tests.
*
* @private
*/
export declare const logs: {
slowAck: import("google-logging-utils").AdhocDebugLogFunction;
ackNack: import("google-logging-utils").AdhocDebugLogFunction;
debug: import("google-logging-utils").AdhocDebugLogFunction;
};
export type PullResponse = google.pubsub.v1.IStreamingPullResponse;
export type SubscriptionProperties = google.pubsub.v1.StreamingPullResponse.ISubscriptionProperties;
type ValueOf<T> = T[keyof T];
export declare const AckResponses: {
PermissionDenied: "PERMISSION_DENIED";
FailedPrecondition: "FAILED_PRECONDITION";
Success: "SUCCESS";
Invalid: "INVALID";
Other: "OTHER";
};
export type AckResponse = ValueOf<typeof AckResponses>;
/**
* Enum values for behaviors of the Subscriber.close() method.
*/
export declare const SubscriberCloseBehaviors: {
NackImmediately: "NACK";
WaitForProcessing: "WAIT";
};
export type SubscriberCloseBehavior = ValueOf<typeof SubscriberCloseBehaviors>;
/**
* Options to modify the behavior of the Subscriber.close() method. If
* none is passed, the default is SubscriberCloseBehaviors.Wait.
*/
export interface SubscriberCloseOptions {
behavior?: SubscriberCloseBehavior;
timeout?: Duration;
}
/**
* Thrown when an error is detected in an ack/nack/modack call, when
* exactly-once delivery is enabled on the subscription. This will
* only be thrown for actual errors that can't be retried.
*/
export declare class AckError extends Error {
errorCode: AckResponse;
constructor(errorCode: AckResponse, message?: string);
}
/**
* Tracks the various spans related to subscriber/receive tracing.
*
* @private
*/
export declare class SubscriberSpans {
parent: tracing.MessageWithAttributes;
constructor(parent: tracing.MessageWithAttributes);
flowStart(): void;
flowEnd(): void;
ackStart(): void;
ackEnd(): void;
ackCall(): void;
nackStart(): void;
nackEnd(): void;
nackCall(): void;
modAckStart(deadline: Duration, isInitial: boolean): void;
modAckEnd(): void;
modAckCall(deadline: Duration): void;
schedulerStart(): void;
schedulerEnd(): void;
processingStart(subName: string): void;
processingEnd(): void;
shutdown(): void;
private flow?;
private scheduler?;
private processing?;
}
/**
* Date object with nanosecond precision. Supports all standard Date arguments
* in addition to several custom types.
*
* @external PreciseDate
* @see {@link https://github.com/googleapis/nodejs-precise-date|PreciseDate}
*/
/**
* Message objects provide a simple interface for users to get message data and
* acknowledge the message.
*
* @example
* ```
* subscription.on('message', message => {
* // {
* // ackId: 'RUFeQBJMJAxESVMrQwsqWBFOBCEhPjA',
* // attributes: {key: 'value'},
* // data: Buffer.from('Hello, world!'),
* // id: '1551297743043',
* // orderingKey: 'ordering-key',
* // publishTime: new PreciseDate('2019-02-27T20:02:19.029534186Z'),
* // received: 1551297743043,
* // length: 13
* // }
* });
* ```
*/
export declare class Message implements tracing.MessageWithAttributes {
ackId: string;
attributes: {
[key: string]: string;
};
data: Buffer;
deliveryAttempt: number;
id: string;
orderingKey?: string;
publishTime: PreciseDate;
received: number;
private _handledPromise;
private _handled;
private _length;
private _subscriber;
private _ackFailed?;
private _dispatched;
/**
* @private
*
* Tracks a telemetry tracing parent span through the receive process. This will
* be the original publisher-side span if we have one; otherwise we'll create
* a "publisher" span to hang new subscriber spans onto.
*
* This needs to be declared explicitly here, because having a public class
* implement a private interface seems to confuse TypeScript. (And it's needed
* in unit tests.)
*/
parentSpan?: tracing.Span;
/**
* @private
*
* Ends any open subscribe telemetry tracing span.
*/
endParentSpan(): void;
/**
* @private
*
* Tracks subscriber-specific telemetry objects through the library.
*/
subSpans: SubscriberSpans;
/**
* @hideconstructor
*
* @param {Subscriber} sub The parent subscriber.
* @param {object} message The raw message response.
*/
constructor(sub: Subscriber, { ackId, message, deliveryAttempt }: google.pubsub.v1.IReceivedMessage);
/**
* The length of the message data.
*
* @type {number}
*/
get length(): number;
/**
* Resolves when the message has been handled fully; a handled message may
* not have any further operations performed on it.
*
* @private
*/
get handledPromise(): Promise<void>;
/**
* When this message is dispensed to user callback code, this should be called.
* The time between the dispatch and the handledPromise resolving is when the
* message is with the user.
*
* @private
*/
dispatched(): void;
/**
* @private
* @returns True if this message has been dispatched to user callback code.
*/
isDispatched(): boolean;
/**
* Sets this message's exactly once delivery acks to permanent failure. This is
* meant for internal library use only.
*
* @private
*/
ackFailed(error: AckError): void;
/**
* Acknowledges the message.
*
* @example
* ```
* subscription.on('message', message => {
* message.ack();
* });
* ```
*/
ack(): void;
/**
* Acknowledges the message, expecting a response (for exactly-once delivery subscriptions).
* If exactly-once delivery is not enabled, this will immediately resolve successfully.
*
* @example
* ```
* subscription.on('message', async (message) => {
* const response = await message.ackWithResponse();
* });
* ```
*/
ackWithResponse(): Promise<AckResponse>;
/**
* Modifies the ack deadline.
* At present time, this should generally not be called by users.
*
* @param {number} deadline The number of seconds to extend the deadline.
* @private
*/
modAck(deadline: number): void;
/**
* Modifies the ack deadline, expecting a response (for exactly-once delivery subscriptions).
* If exactly-once delivery is not enabled, this will immediately resolve successfully.
* At present time, this should generally not be called by users.
*
* @param {number} deadline The number of seconds to extend the deadline.
* @private
*/
modAckWithResponse(deadline: number): Promise<AckResponse>;
/**
* Removes the message from our inventory and schedules it to be redelivered.
*
* @example
* ```
* subscription.on('message', message => {
* message.nack();
* });
* ```
*/
nack(): void;
/**
* Removes the message from our inventory and schedules it to be redelivered,
* with the modAck response being returned (for exactly-once delivery subscriptions).
* If exactly-once delivery is not enabled, this will immediately resolve successfully.
*
* @example
* ```
* subscription.on('message', async (message) => {
* const response = await message.nackWithResponse();
* });
* ```
*/
nackWithResponse(): Promise<AckResponse>;
}
/**
* @typedef {object} SubscriberOptions
* @property {number} [ackDeadline=10] Acknowledge deadline in seconds. If left
* unset, the initial value will be 10 seconds, but it will evolve into the
* 99th percentile time it takes to acknowledge a message, subject to the
* limitations of minAckDeadline and maxAckDeadline. If ackDeadline is set
* by the user, then the min/max values will be set to match it. New code
* should prefer setting minAckDeadline and maxAckDeadline directly.
* @property {Duration} [minAckDeadline] The minimum time that ackDeadline should
* ever have, while it's under library control.
* @property {Duration} [maxAckDeadline] The maximum time that ackDeadline should
* ever have, while it's under library control.
* @property {Duration} [maxExtensionTime] The maximum time that ackDeadline should
* ever have, while it's under library control.
* @property {BatchOptions} [batching] Request batching options; this is for
* batching acks and modacks being sent back to the server.
* @property {FlowControlOptions} [flowControl] Flow control options.
* @property {boolean} [useLegacyFlowControl] Disables enforcing flow control
* settings at the Cloud PubSub server and uses the less accurate method
* of only enforcing flow control at the client side.
* @property {MessageStreamOptions} [streamingOptions] Streaming options.
* If no options are passed, it behaves like `SubscriberCloseBehaviors.Wait`.
* @property {SubscriberCloseOptions} [options] Determines the basic behavior of the
* close() function.
* @property {SubscriberCloseBehavior} [options.behavior] The behavior of the close operation.
* - NackImmediately: Sends nacks for all messages held by the client library, and
* wait for them to send.
* - WaitForProcessing: Continues normal ack/nack and leasing processes until close
* to the timeout, then switches to NackImmediately behavior to close down.
* Use {@link SubscriberCloseBehaviors} for enum values.
* @property {Duration} [options.timeout] In the case of Timeout, the maximum duration
* to wait for pending ack/nack requests to complete before resolving (or rejecting)
* the promise.
*/
export interface SubscriberOptions {
minAckDeadline?: Duration;
maxAckDeadline?: Duration;
maxExtensionTime?: Duration;
batching?: BatchOptions;
flowControl?: FlowControlOptions;
useLegacyFlowControl?: boolean;
streamingOptions?: MessageStreamOptions;
closeOptions?: SubscriberCloseOptions;
}
/**
* Subscriber class is used to manage all message related functionality.
*
* @private
* @class
*
* @param {Subscription} subscription The corresponding subscription.
* @param {SubscriberOptions} options The subscriber options.
*/
export declare class Subscriber extends EventEmitter {
#private;
ackDeadline: number;
maxMessages: number;
maxBytes: number;
useLegacyFlowControl: boolean;
isOpen: boolean;
maxExtensionTime: Duration;
private _acks;
private _histogram;
private _inventory;
private _latencies;
private _modAcks;
private _name;
private _options;
private _stream;
private _subscription;
private _99th;
subscriptionProperties?: SubscriptionProperties;
constructor(subscription: Subscription, options?: {});
/**
* Update our ack extension time that will be used by the lease manager
* for sending modAcks.
*
* Should not be called from outside this class, except for unit tests.
*
* @param {number} [ackTimeSeconds] The number of seconds that the last
* ack took after the message was received. If this is undefined, then
* we won't update the histogram, but we will still recalculate the
* ackDeadline based on the situation.
*
* @private
*/
updateAckDeadline(ackTimeSeconds?: number): void;
private getMinMaxDeadlines;
/**
* Returns true if an exactly-once delivery subscription has been detected.
*
* @private
*/
get isExactlyOnceDelivery(): boolean;
/**
* Sets our subscription properties from incoming messages.
*
* @param {SubscriptionProperties} subscriptionProperties The new properties.
* @private
*/
setSubscriptionProperties(subscriptionProperties: SubscriptionProperties): void;
/**
* The 99th percentile of request latencies.
*
* @type {number}
* @private
*/
get modAckLatency(): number;
/**
* The full name of the Subscription.
*
* @type {string}
* @private
*/
get name(): string;
/**
* Acknowledges the supplied message.
*
* @param {Message} message The message to acknowledge.
* @returns {Promise<void>}
* @private
*/
ack(message: Message): Promise<void>;
/**
* Acknowledges the supplied message, expecting a response (for exactly
* once subscriptions).
*
* @param {Message} message The message to acknowledge.
* @returns {Promise<AckResponse>}
* @private
*/
ackWithResponse(message: Message): Promise<AckResponse>;
/**
* Closes the subscriber, stopping the reception of new messages and shutting
* down the underlying stream. The behavior of the returned Promise will depend
* on the closeOptions in the subscriber options.
*
* @returns {Promise<void>} A promise that resolves when the subscriber is closed
* and pending operations are flushed or the timeout is reached.
*
* @private
*/
close(): Promise<void>;
/**
* Gets the subscriber client instance.
*
* @returns {Promise<object>}
* @private
*/
getClient(): Promise<SubscriberClient>;
/**
* Modifies the acknowledge deadline for the provided message.
*
* @param {Message} message The message to modify.
* @param {number} deadline The deadline in seconds.
* @returns {Promise<void>}
* @private
*/
modAck(message: Message, deadline: number): Promise<void>;
/**
* Modifies the acknowledge deadline for the provided message, expecting
* a reply (for exactly-once delivery subscriptions).
*
* @param {Message} message The message to modify.
* @param {number} deadline The deadline.
* @returns {Promise<AckResponse>}
* @private
*/
modAckWithResponse(message: Message, deadline: number): Promise<AckResponse>;
/**
* Modfies the acknowledge deadline for the provided message and then removes
* it from our inventory.
*
* @param {Message} message The message.
* @return {Promise<void>}
* @private
*/
nack(message: Message): Promise<void>;
/**
* Modfies the acknowledge deadline for the provided message and then removes
* it from our inventory, expecting a response from modAck (for
* exactly-once delivery subscriptions).
*
* @param {Message} message The message.
* @return {Promise<AckResponse>}
* @private
*/
nackWithResponse(message: Message): Promise<AckResponse>;
/**
* Starts pulling messages.
* @private
*/
open(): void;
/**
* Sets subscriber options.
*
* @param {SubscriberOptions} options The options.
* @private
*/
setOptions(options: SubscriberOptions): void;
/**
* Retrieves our effective options. This is mostly for unit test use.
*
* @private
* @returns {SubscriberOptions} The options.
*/
getOptions(): SubscriberOptions;
/**
* Constructs a telemetry span from the incoming message.
*
* @param {Message} message One of the received messages
* @private
*/
private createParentSpan;
/**
* Callback to be invoked when a new message is available.
*
* New messages will be added to the subscribers inventory, which in turn will
* automatically extend the messages ack deadline until either:
* a. the user acks/nacks it
* b. the maxExtension option is hit
*
* If the message puts us at/over capacity, then we'll pause our message
* stream until we've freed up some inventory space.
*
* New messages must immediately issue a ModifyAckDeadline request
* (aka receipt) to confirm with the backend that we did infact receive the
* message and its ok to start ticking down on the deadline.
*
* @private
*/
private _onData;
private _discardMessage;
/**
* Returns a promise that will resolve once all pending requests have settled.
*
* @private
*
* @returns {Promise<void>}
*/
private _waitForFlush;
}