diff --git a/CHANGELOG.md b/CHANGELOG.md index 5429baa7..7ec71d65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### New +- Add the DTS payload-purge protocol and `setLargePayloadAutoPurge()` client lifecycle, + including setting-first enable/disable and reserved-instance identity verification. + A compatible .NET worker or the later cleanup-worker phase is required; do not publish partial phases. - Add payload storage contracts and bounded protobuf payload processing, with inclusive UTF-8 thresholds, explicit storage/size failures, and non-retriable worker upload-failure conversion. This is phase 1 of the external-payload feature; transport, providers, and cleanup follow separately. @@ -47,6 +50,8 @@ ### Fixes +- Determine single-instance purge routing from the instance ID regardless of payload configuration, + matching .NET management clients: ordinary IDs are orchestrations and `@name@key` IDs are entities. - Prevent shared or duplicate pending tasks from stranding `whenAll` orchestrations after all activities finish. Notify every dependent composite, preserve duplicate result positions, and detach completed `whenAny` groups from their remaining children. diff --git a/README.md b/README.md index 17ffbf62..3367f293 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,22 @@ Azure-managed builders expose `.useExternalizedPayloads({ store })` and require for the public payload types. This phase works with a custom/in-memory store and does not import an Azure Blob provider or register cleanup tasks. Complete the six-phase feature stack before release. +### Payload cleanup client protocol + +`client.setLargePayloadAutoPurge(enabled, batchSize?, signal?)` manages the authenticated DTS +task-hub cleanup setting. Enabling writes the setting first, starts/deduplicates and verifies +the reserved Running orchestration, then signals its batch size. Disabling only writes the +backend setting. These steps are not transactional; earlier successful steps are not rolled back. + +This client operation does not require blob credentials. It requires a backend implementing +the DTS `LargePayloadPurge` service and a compatible worker (the existing .NET implementation +or the later phase 5 JavaScript runner). This phase does not register worker cleanup tasks. +Do not publish the feature until all six phases are complete. + +Single-instance purges now identify the instance kind even on management-only clients without +payload storage: ordinary IDs set `isOrchestration=true`, while `@name@key` entity IDs set it false. +The existing timeout and completion-status behavior is unchanged. + ## Long durable timers `createTimer(Date | seconds)` has no SDK-imposed total-duration cap. Like the Python SDK, diff --git a/internal/protocol/protos/large_payload_purge.proto b/internal/protocol/protos/large_payload_purge.proto new file mode 100644 index 00000000..c615ffff --- /dev/null +++ b/internal/protocol/protos/large_payload_purge.proto @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// DTS-only contract from durabletask-dotnet 91739687ff647699079cdadd627daa00562982b7. + +syntax = "proto3"; + +package microsoft.durabletask.largepayloads; + +option csharp_namespace = "Microsoft.DurableTask.Protobuf.LargePayloads"; + +// The backend owns the tombstone ledger, task-hub setting, and retry scheduling. +// The credentialed worker performs ownership-checked blob deletes and reports outcomes. +service LargePayloadPurge { + rpc SetLargePayloadAutoPurge(SetLargePayloadAutoPurgeRequest) returns (SetLargePayloadAutoPurgeResponse); + rpc GetLargePayloadTombstones(GetLargePayloadTombstonesRequest) returns (GetLargePayloadTombstonesResponse); + rpc ReportLargePayloadPurgeResults(ReportLargePayloadPurgeResultsRequest) returns (ReportLargePayloadPurgeResultsResponse); +} + +message SetLargePayloadAutoPurgeRequest { + bool enabled = 1; +} + +message SetLargePayloadAutoPurgeResponse {} + +message LargePayloadTombstone { + // Opaque correlation token. Echo unchanged; never parse or reconstruct it. + string tombstone_token = 1; + string payload_token = 2; +} + +enum LargePayloadPurgeDisposition { + LARGE_PAYLOAD_PURGE_DISPOSITION_UNSPECIFIED = 0; + LARGE_PAYLOAD_PURGE_DISPOSITION_DELETED = 1; + LARGE_PAYLOAD_PURGE_DISPOSITION_RETRY = 2; + LARGE_PAYLOAD_PURGE_DISPOSITION_QUARANTINED = 3; +} + +message LargePayloadPurgeResult { + string tombstone_token = 1; + LargePayloadPurgeDisposition disposition = 2; +} + +message GetLargePayloadTombstonesRequest { + int32 limit = 1; +} + +message GetLargePayloadTombstonesResponse { + repeated LargePayloadTombstone tombstones = 1; +} + +message ReportLargePayloadPurgeResultsRequest { + repeated LargePayloadPurgeResult results = 1; +} + +message ReportLargePayloadPurgeResultsResponse {} diff --git a/packages/durabletask-js/src/client/client.ts b/packages/durabletask-js/src/client/client.ts index f71ba9fc..7e862eff 100644 --- a/packages/durabletask-js/src/client/client.ts +++ b/packages/durabletask-js/src/client/client.ts @@ -40,6 +40,10 @@ import { SignalEntityOptions } from "../entities/signal-entity-options"; import { PayloadStorageOptions } from "../payloads/payload-store"; import { PayloadProcessor } from "../payloads/payload-processor"; import { readPayloadHistory, PayloadHydrationError } from "../payloads/history-stream"; +import * as lp from "../proto/large_payload_purge_pb"; +import { LargePayloadPurgeService } from "../proto/large_payload_purge_grpc_pb"; +import { callPayloadPurge } from "../payloads/purge-transport"; +import { BlobPurgeConstants, validatePurgeBatchSize } from "../payloads/purge"; import { CleanEntityStorageRequest, CleanEntityStorageResult, @@ -186,6 +190,79 @@ export class TaskHubGrpcClient { return response; } + /** + * Enables or pauses DTS large-payload cleanup. Enabling starts/verifies the reserved singleton + * and enqueues its batch size (1..1000, default 500). Disabling only writes the backend setting. + * Steps are not transactional; errors and cancellation do not roll back an earlier successful step. + * A payload-enabled worker is required. Legacy v1 references are not deleted. + */ + async setLargePayloadAutoPurge(enabled: boolean, batchSize = 500, signal?: AbortSignal): Promise { + if (enabled) validatePurgeBatchSize(batchSize); + const cancellation = signal + ? AbortSignal.any([signal, this._payloadCancellation.signal]) + : this._payloadCancellation.signal; + await callPayloadPurge( + this._stub, + LargePayloadPurgeService.setLargePayloadAutoPurge, + new lp.SetLargePayloadAutoPurgeRequest().setEnabled(enabled), + this._metadataGenerator, + cancellation, + ); + if (!enabled) return; + const request = new pb.CreateInstanceRequest() + .setInstanceid(BlobPurgeConstants.instanceId) + .setName(BlobPurgeConstants.orchestrator) + .setVersion(new StringValue().setValue("")) + .setInput(new StringValue().setValue(JSON.stringify({ PurgeBatchSize: batchSize, PurgedCount: 0 }))) + .setOrchestrationidreusepolicy( + new pb.OrchestrationIdReusePolicy().setReplaceablestatusList([ + pb.OrchestrationStatus.ORCHESTRATION_STATUS_COMPLETED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_FAILED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_CANCELED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_TERMINATED, + ]), + ); + try { + const response = await this._call( + this._stub.startInstance.bind(this._stub), + request, + this._metadataGenerator, + cancellation, + ); + if (response.getInstanceid() !== BlobPurgeConstants.instanceId) { + throw new Error("The backend returned an unexpected auto-purge instance ID."); + } + } catch (error) { + if (!(error instanceof Error && "code" in error && error.code === grpc.status.ALREADY_EXISTS)) throw error; + } + const started = await this._call( + this._stub.waitForInstanceStart.bind(this._stub), + new pb.GetInstanceRequest().setInstanceid(BlobPurgeConstants.instanceId).setGetinputsandoutputs(false), + this._metadataGenerator, + cancellation, + ); + const state = started.getOrchestrationstate(); + if ( + !started.getExists() || + state?.getInstanceid() !== BlobPurgeConstants.instanceId || + state?.getName() !== BlobPurgeConstants.orchestrator + ) { + throw new Error("The reserved auto-purge instance ID belongs to a different orchestration."); + } + if (state.getOrchestrationstatus() !== pb.OrchestrationStatus.ORCHESTRATION_STATUS_RUNNING) { + throw new Error("Auto-purge did not start in Running status."); + } + await this._call( + this._stub.raiseEvent.bind(this._stub), + new pb.RaiseEventRequest() + .setInstanceid(BlobPurgeConstants.instanceId) + .setName(BlobPurgeConstants.configurationEvent) + .setInput(new StringValue().setValue(JSON.stringify(batchSize))), + this._metadataGenerator, + cancellation, + ); + } + /** * Schedules a new orchestrator using the DurableTask client. * @@ -797,6 +874,7 @@ export class TaskHubGrpcClient { const req = new pb.PurgeInstancesRequest(); req.setInstanceid(instanceId); req.setRecursive(options?.recursive ?? false); + req.setIsorchestration(!instanceId.startsWith("@")); ClientLogs.purgingInstanceMetadata(this._logger, instanceId); diff --git a/packages/durabletask-js/src/index.ts b/packages/durabletask-js/src/index.ts index 5e22ec89..f319c996 100644 --- a/packages/durabletask-js/src/index.ts +++ b/packages/durabletask-js/src/index.ts @@ -8,6 +8,7 @@ export { PayloadStorageException, PayloadDeleteOutcome, } from "./payloads/payload-store"; +export { LargePayloadPurgeDisposition, LargePayloadTombstone, LargePayloadPurgeResult } from "./payloads/purge"; export { TaskHubGrpcClient, TaskHubGrpcClientOptions, MetadataGenerator } from "./client/client"; export { TaskHubGrpcWorker, TaskHubGrpcWorkerOptions } from "./worker/task-hub-grpc-worker"; export { ConcurrencyOptions } from "./worker/concurrency-options"; diff --git a/packages/durabletask-js/src/payloads/purge-transport.ts b/packages/durabletask-js/src/payloads/purge-transport.ts new file mode 100644 index 00000000..62bfd7ee --- /dev/null +++ b/packages/durabletask-js/src/payloads/purge-transport.ts @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as grpc from "@grpc/grpc-js"; +import { callWithMetadata, MetadataGenerator } from "../utils/grpc-helper.util"; + +/** Reuses the effective sidecar's authenticated channel, including after worker channel recreation. */ +export async function callPayloadPurge( + client: grpc.Client, + definition: grpc.MethodDefinition, + request: TReq, + metadataGenerator?: MetadataGenerator, + signal?: AbortSignal, + deadline?: Date, +): Promise { + const response = await callWithMetadata( + (req, metadata, callback) => + client.makeUnaryRequest( + definition.path, + definition.requestSerialize, + definition.responseDeserialize, + req, + metadata, + { deadline }, + callback, + ), + request, + metadataGenerator, + signal, + ); + if (response === undefined) throw new Error("The large-payload purge RPC returned no response."); + return response; +} diff --git a/packages/durabletask-js/src/payloads/purge.ts b/packages/durabletask-js/src/payloads/purge.ts new file mode 100644 index 00000000..b989daa6 --- /dev/null +++ b/packages/durabletask-js/src/payloads/purge.ts @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +export const BlobPurgeConstants = { + orchestrator: "BlobPurgeJobOrchestrator", + instanceId: "BlobPurgeJob-__dt_blob_payload_autopurge__", + fetch: "GetLargePayloadTombstonesActivity", + delete: "DeleteExternalBlobActivity", + report: "ReportLargePayloadPurgeResultsActivity", + configurationEvent: "SetBatchSize", +} as const; + +export enum LargePayloadPurgeDisposition { + Unspecified = 0, + Deleted = 1, + Retry = 2, + Quarantined = 3, +} + +// These activity/orchestration wire shapes intentionally retain .NET's default JSON property casing. +export interface LargePayloadTombstone { + TombstoneToken: string; + PayloadToken: string; +} +export interface LargePayloadPurgeResult { + TombstoneToken: string; + Disposition: LargePayloadPurgeDisposition; +} +export interface BlobPurgeOutcome { + Disposition: LargePayloadPurgeDisposition; +} +export interface BlobPurgeJobRunRequest { + PurgeBatchSize: number; + PurgedCount: number; +} + +export function validatePurgeBatchSize(batchSize: number): void { + if (!Number.isInteger(batchSize) || batchSize < 1 || batchSize > 1000) { + throw new RangeError("Purge batch size must be an integer between 1 and 1000."); + } +} diff --git a/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.d.ts b/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.d.ts new file mode 100644 index 00000000..64917153 --- /dev/null +++ b/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.d.ts @@ -0,0 +1,75 @@ +// package: microsoft.durabletask.largepayloads +// file: large_payload_purge.proto + +/* tslint:disable */ +/* eslint-disable */ + +import * as grpc from "@grpc/grpc-js"; +import * as large_payload_purge_pb from "./large_payload_purge_pb"; + +interface ILargePayloadPurgeService extends grpc.ServiceDefinition { + setLargePayloadAutoPurge: ILargePayloadPurgeService_ISetLargePayloadAutoPurge; + getLargePayloadTombstones: ILargePayloadPurgeService_IGetLargePayloadTombstones; + reportLargePayloadPurgeResults: ILargePayloadPurgeService_IReportLargePayloadPurgeResults; +} + +interface ILargePayloadPurgeService_ISetLargePayloadAutoPurge extends grpc.MethodDefinition { + path: "/microsoft.durabletask.largepayloads.LargePayloadPurge/SetLargePayloadAutoPurge"; + requestStream: false; + responseStream: false; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} +interface ILargePayloadPurgeService_IGetLargePayloadTombstones extends grpc.MethodDefinition { + path: "/microsoft.durabletask.largepayloads.LargePayloadPurge/GetLargePayloadTombstones"; + requestStream: false; + responseStream: false; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} +interface ILargePayloadPurgeService_IReportLargePayloadPurgeResults extends grpc.MethodDefinition { + path: "/microsoft.durabletask.largepayloads.LargePayloadPurge/ReportLargePayloadPurgeResults"; + requestStream: false; + responseStream: false; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} + +export const LargePayloadPurgeService: ILargePayloadPurgeService; + +export interface ILargePayloadPurgeServer extends grpc.UntypedServiceImplementation { + setLargePayloadAutoPurge: grpc.handleUnaryCall; + getLargePayloadTombstones: grpc.handleUnaryCall; + reportLargePayloadPurgeResults: grpc.handleUnaryCall; +} + +export interface ILargePayloadPurgeClient { + setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; + reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; + reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; +} + +export class LargePayloadPurgeClient extends grpc.Client implements ILargePayloadPurgeClient { + constructor(address: string, credentials: grpc.ChannelCredentials, options?: Partial); + public setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + public setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + public setLargePayloadAutoPurge(request: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse) => void): grpc.ClientUnaryCall; + public getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + public getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + public getLargePayloadTombstones(request: large_payload_purge_pb.GetLargePayloadTombstonesRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.GetLargePayloadTombstonesResponse) => void): grpc.ClientUnaryCall; + public reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; + public reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; + public reportLargePayloadPurgeResults(request: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse) => void): grpc.ClientUnaryCall; +} diff --git a/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.js b/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.js new file mode 100644 index 00000000..58a51048 --- /dev/null +++ b/packages/durabletask-js/src/proto/large_payload_purge_grpc_pb.js @@ -0,0 +1,118 @@ +// GENERATED CODE -- DO NOT EDIT! + +// Original file comments: +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// DTS-only contract from durabletask-dotnet 91739687ff647699079cdadd627daa00562982b7. +// +'use strict'; +var grpc = require('@grpc/grpc-js'); +var large_payload_purge_pb = require('./large_payload_purge_pb.js'); + +function serialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesRequest(arg) { + if (!(arg instanceof large_payload_purge_pb.GetLargePayloadTombstonesRequest)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesRequest(buffer_arg) { + return large_payload_purge_pb.GetLargePayloadTombstonesRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesResponse(arg) { + if (!(arg instanceof large_payload_purge_pb.GetLargePayloadTombstonesResponse)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesResponse(buffer_arg) { + return large_payload_purge_pb.GetLargePayloadTombstonesResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsRequest(arg) { + if (!(arg instanceof large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsRequest(buffer_arg) { + return large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsResponse(arg) { + if (!(arg instanceof large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsResponse(buffer_arg) { + return large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeRequest(arg) { + if (!(arg instanceof large_payload_purge_pb.SetLargePayloadAutoPurgeRequest)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeRequest(buffer_arg) { + return large_payload_purge_pb.SetLargePayloadAutoPurgeRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeResponse(arg) { + if (!(arg instanceof large_payload_purge_pb.SetLargePayloadAutoPurgeResponse)) { + throw new Error('Expected argument of type microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeResponse(buffer_arg) { + return large_payload_purge_pb.SetLargePayloadAutoPurgeResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + + +// The backend owns the tombstone ledger, task-hub setting, and retry scheduling. +// The credentialed worker performs ownership-checked blob deletes and reports outcomes. +var LargePayloadPurgeService = exports.LargePayloadPurgeService = { + setLargePayloadAutoPurge: { + path: '/microsoft.durabletask.largepayloads.LargePayloadPurge/SetLargePayloadAutoPurge', + requestStream: false, + responseStream: false, + requestType: large_payload_purge_pb.SetLargePayloadAutoPurgeRequest, + responseType: large_payload_purge_pb.SetLargePayloadAutoPurgeResponse, + requestSerialize: serialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeRequest, + requestDeserialize: deserialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeRequest, + responseSerialize: serialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeResponse, + responseDeserialize: deserialize_microsoft_durabletask_largepayloads_SetLargePayloadAutoPurgeResponse, + }, + getLargePayloadTombstones: { + path: '/microsoft.durabletask.largepayloads.LargePayloadPurge/GetLargePayloadTombstones', + requestStream: false, + responseStream: false, + requestType: large_payload_purge_pb.GetLargePayloadTombstonesRequest, + responseType: large_payload_purge_pb.GetLargePayloadTombstonesResponse, + requestSerialize: serialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesRequest, + requestDeserialize: deserialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesRequest, + responseSerialize: serialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesResponse, + responseDeserialize: deserialize_microsoft_durabletask_largepayloads_GetLargePayloadTombstonesResponse, + }, + reportLargePayloadPurgeResults: { + path: '/microsoft.durabletask.largepayloads.LargePayloadPurge/ReportLargePayloadPurgeResults', + requestStream: false, + responseStream: false, + requestType: large_payload_purge_pb.ReportLargePayloadPurgeResultsRequest, + responseType: large_payload_purge_pb.ReportLargePayloadPurgeResultsResponse, + requestSerialize: serialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsRequest, + requestDeserialize: deserialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsRequest, + responseSerialize: serialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsResponse, + responseDeserialize: deserialize_microsoft_durabletask_largepayloads_ReportLargePayloadPurgeResultsResponse, + }, +}; + +exports.LargePayloadPurgeClient = grpc.makeGenericClientConstructor(LargePayloadPurgeService, 'LargePayloadPurge'); diff --git a/packages/durabletask-js/src/proto/large_payload_purge_pb.d.ts b/packages/durabletask-js/src/proto/large_payload_purge_pb.d.ts new file mode 100644 index 00000000..de303194 --- /dev/null +++ b/packages/durabletask-js/src/proto/large_payload_purge_pb.d.ts @@ -0,0 +1,178 @@ +// package: microsoft.durabletask.largepayloads +// file: large_payload_purge.proto + +/* tslint:disable */ +/* eslint-disable */ + +import * as jspb from "google-protobuf"; + +export class SetLargePayloadAutoPurgeRequest extends jspb.Message { + getEnabled(): boolean; + setEnabled(value: boolean): SetLargePayloadAutoPurgeRequest; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): SetLargePayloadAutoPurgeRequest.AsObject; + static toObject(includeInstance: boolean, msg: SetLargePayloadAutoPurgeRequest): SetLargePayloadAutoPurgeRequest.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: SetLargePayloadAutoPurgeRequest, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): SetLargePayloadAutoPurgeRequest; + static deserializeBinaryFromReader(message: SetLargePayloadAutoPurgeRequest, reader: jspb.BinaryReader): SetLargePayloadAutoPurgeRequest; +} + +export namespace SetLargePayloadAutoPurgeRequest { + export type AsObject = { + enabled: boolean, + } +} + +export class SetLargePayloadAutoPurgeResponse extends jspb.Message { + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): SetLargePayloadAutoPurgeResponse.AsObject; + static toObject(includeInstance: boolean, msg: SetLargePayloadAutoPurgeResponse): SetLargePayloadAutoPurgeResponse.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: SetLargePayloadAutoPurgeResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): SetLargePayloadAutoPurgeResponse; + static deserializeBinaryFromReader(message: SetLargePayloadAutoPurgeResponse, reader: jspb.BinaryReader): SetLargePayloadAutoPurgeResponse; +} + +export namespace SetLargePayloadAutoPurgeResponse { + export type AsObject = { + } +} + +export class LargePayloadTombstone extends jspb.Message { + getTombstoneToken(): string; + setTombstoneToken(value: string): LargePayloadTombstone; + getPayloadToken(): string; + setPayloadToken(value: string): LargePayloadTombstone; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): LargePayloadTombstone.AsObject; + static toObject(includeInstance: boolean, msg: LargePayloadTombstone): LargePayloadTombstone.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: LargePayloadTombstone, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): LargePayloadTombstone; + static deserializeBinaryFromReader(message: LargePayloadTombstone, reader: jspb.BinaryReader): LargePayloadTombstone; +} + +export namespace LargePayloadTombstone { + export type AsObject = { + tombstoneToken: string, + payloadToken: string, + } +} + +export class LargePayloadPurgeResult extends jspb.Message { + getTombstoneToken(): string; + setTombstoneToken(value: string): LargePayloadPurgeResult; + getDisposition(): LargePayloadPurgeDisposition; + setDisposition(value: LargePayloadPurgeDisposition): LargePayloadPurgeResult; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): LargePayloadPurgeResult.AsObject; + static toObject(includeInstance: boolean, msg: LargePayloadPurgeResult): LargePayloadPurgeResult.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: LargePayloadPurgeResult, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): LargePayloadPurgeResult; + static deserializeBinaryFromReader(message: LargePayloadPurgeResult, reader: jspb.BinaryReader): LargePayloadPurgeResult; +} + +export namespace LargePayloadPurgeResult { + export type AsObject = { + tombstoneToken: string, + disposition: LargePayloadPurgeDisposition, + } +} + +export class GetLargePayloadTombstonesRequest extends jspb.Message { + getLimit(): number; + setLimit(value: number): GetLargePayloadTombstonesRequest; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): GetLargePayloadTombstonesRequest.AsObject; + static toObject(includeInstance: boolean, msg: GetLargePayloadTombstonesRequest): GetLargePayloadTombstonesRequest.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: GetLargePayloadTombstonesRequest, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): GetLargePayloadTombstonesRequest; + static deserializeBinaryFromReader(message: GetLargePayloadTombstonesRequest, reader: jspb.BinaryReader): GetLargePayloadTombstonesRequest; +} + +export namespace GetLargePayloadTombstonesRequest { + export type AsObject = { + limit: number, + } +} + +export class GetLargePayloadTombstonesResponse extends jspb.Message { + clearTombstonesList(): void; + getTombstonesList(): Array; + setTombstonesList(value: Array): GetLargePayloadTombstonesResponse; + addTombstones(value?: LargePayloadTombstone, index?: number): LargePayloadTombstone; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): GetLargePayloadTombstonesResponse.AsObject; + static toObject(includeInstance: boolean, msg: GetLargePayloadTombstonesResponse): GetLargePayloadTombstonesResponse.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: GetLargePayloadTombstonesResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): GetLargePayloadTombstonesResponse; + static deserializeBinaryFromReader(message: GetLargePayloadTombstonesResponse, reader: jspb.BinaryReader): GetLargePayloadTombstonesResponse; +} + +export namespace GetLargePayloadTombstonesResponse { + export type AsObject = { + tombstonesList: Array, + } +} + +export class ReportLargePayloadPurgeResultsRequest extends jspb.Message { + clearResultsList(): void; + getResultsList(): Array; + setResultsList(value: Array): ReportLargePayloadPurgeResultsRequest; + addResults(value?: LargePayloadPurgeResult, index?: number): LargePayloadPurgeResult; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ReportLargePayloadPurgeResultsRequest.AsObject; + static toObject(includeInstance: boolean, msg: ReportLargePayloadPurgeResultsRequest): ReportLargePayloadPurgeResultsRequest.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: ReportLargePayloadPurgeResultsRequest, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ReportLargePayloadPurgeResultsRequest; + static deserializeBinaryFromReader(message: ReportLargePayloadPurgeResultsRequest, reader: jspb.BinaryReader): ReportLargePayloadPurgeResultsRequest; +} + +export namespace ReportLargePayloadPurgeResultsRequest { + export type AsObject = { + resultsList: Array, + } +} + +export class ReportLargePayloadPurgeResultsResponse extends jspb.Message { + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ReportLargePayloadPurgeResultsResponse.AsObject; + static toObject(includeInstance: boolean, msg: ReportLargePayloadPurgeResultsResponse): ReportLargePayloadPurgeResultsResponse.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: ReportLargePayloadPurgeResultsResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ReportLargePayloadPurgeResultsResponse; + static deserializeBinaryFromReader(message: ReportLargePayloadPurgeResultsResponse, reader: jspb.BinaryReader): ReportLargePayloadPurgeResultsResponse; +} + +export namespace ReportLargePayloadPurgeResultsResponse { + export type AsObject = { + } +} + +export enum LargePayloadPurgeDisposition { + LARGE_PAYLOAD_PURGE_DISPOSITION_UNSPECIFIED = 0, + LARGE_PAYLOAD_PURGE_DISPOSITION_DELETED = 1, + LARGE_PAYLOAD_PURGE_DISPOSITION_RETRY = 2, + LARGE_PAYLOAD_PURGE_DISPOSITION_QUARANTINED = 3, +} diff --git a/packages/durabletask-js/src/proto/large_payload_purge_pb.js b/packages/durabletask-js/src/proto/large_payload_purge_pb.js new file mode 100644 index 00000000..327f6692 --- /dev/null +++ b/packages/durabletask-js/src/proto/large_payload_purge_pb.js @@ -0,0 +1,1313 @@ +// source: large_payload_purge.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = (function() { + if (this) { return this; } + if (typeof window !== 'undefined') { return window; } + if (typeof global !== 'undefined') { return global; } + if (typeof self !== 'undefined') { return self; } + return Function('return this')(); +}.call(null)); + +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.LargePayloadTombstone', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest', null, global); +goog.exportSymbol('proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.displayName = 'proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.displayName = 'proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.LargePayloadTombstone, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.displayName = 'proto.microsoft.durabletask.largepayloads.LargePayloadTombstone'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.displayName = 'proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.displayName = 'proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.repeatedFields_, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.displayName = 'proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.repeatedFields_, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.displayName = 'proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.displayName = 'proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse'; +} + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.toObject = function(includeInstance, msg) { + var f, obj = { + enabled: jspb.Message.getBooleanFieldWithDefault(msg, 1, false) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest; + return proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setEnabled(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getEnabled(); + if (f) { + writer.writeBool( + 1, + f + ); + } +}; + + +/** + * optional bool enabled = 1; + * @return {boolean} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.prototype.getEnabled = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest} returns this + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeRequest.prototype.setEnabled = function(value) { + return jspb.Message.setProto3BooleanField(this, 1, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.toObject = function(includeInstance, msg) { + var f, obj = { + + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse; + return proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.SetLargePayloadAutoPurgeResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.toObject = function(includeInstance, msg) { + var f, obj = { + tombstoneToken: jspb.Message.getFieldWithDefault(msg, 1, ""), + payloadToken: jspb.Message.getFieldWithDefault(msg, 2, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.LargePayloadTombstone; + return proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setTombstoneToken(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setPayloadToken(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTombstoneToken(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getPayloadToken(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } +}; + + +/** + * optional string tombstone_token = 1; + * @return {string} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.getTombstoneToken = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} returns this + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.setTombstoneToken = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string payload_token = 2; + * @return {string} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.getPayloadToken = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} returns this + */ +proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.prototype.setPayloadToken = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.toObject = function(includeInstance, msg) { + var f, obj = { + tombstoneToken: jspb.Message.getFieldWithDefault(msg, 1, ""), + disposition: jspb.Message.getFieldWithDefault(msg, 2, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult; + return proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setTombstoneToken(value); + break; + case 2: + var value = /** @type {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition} */ (reader.readEnum()); + msg.setDisposition(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTombstoneToken(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getDisposition(); + if (f !== 0.0) { + writer.writeEnum( + 2, + f + ); + } +}; + + +/** + * optional string tombstone_token = 1; + * @return {string} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.getTombstoneToken = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} returns this + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.setTombstoneToken = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional LargePayloadPurgeDisposition disposition = 2; + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.getDisposition = function() { + return /** @type {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition} value + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} returns this + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.prototype.setDisposition = function(value) { + return jspb.Message.setProto3EnumField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.toObject = function(includeInstance, msg) { + var f, obj = { + limit: jspb.Message.getFieldWithDefault(msg, 1, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest; + return proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readInt32()); + msg.setLimit(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getLimit(); + if (f !== 0) { + writer.writeInt32( + 1, + f + ); + } +}; + + +/** + * optional int32 limit = 1; + * @return {number} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.prototype.getLimit = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest} returns this + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesRequest.prototype.setLimit = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.repeatedFields_ = [1]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.toObject = function(includeInstance, msg) { + var f, obj = { + tombstonesList: jspb.Message.toObjectList(msg.getTombstonesList(), + proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse; + return proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new proto.microsoft.durabletask.largepayloads.LargePayloadTombstone; + reader.readMessage(value,proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.deserializeBinaryFromReader); + msg.addTombstones(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTombstonesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 1, + f, + proto.microsoft.durabletask.largepayloads.LargePayloadTombstone.serializeBinaryToWriter + ); + } +}; + + +/** + * repeated LargePayloadTombstone tombstones = 1; + * @return {!Array} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.getTombstonesList = function() { + return /** @type{!Array} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.microsoft.durabletask.largepayloads.LargePayloadTombstone, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} returns this +*/ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.setTombstonesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 1, value); +}; + + +/** + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone=} opt_value + * @param {number=} opt_index + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadTombstone} + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.addTombstones = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.microsoft.durabletask.largepayloads.LargePayloadTombstone, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse} returns this + */ +proto.microsoft.durabletask.largepayloads.GetLargePayloadTombstonesResponse.prototype.clearTombstonesList = function() { + return this.setTombstonesList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.repeatedFields_ = [1]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.toObject = function(includeInstance, msg) { + var f, obj = { + resultsList: jspb.Message.toObjectList(msg.getResultsList(), + proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest; + return proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult; + reader.readMessage(value,proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.deserializeBinaryFromReader); + msg.addResults(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getResultsList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 1, + f, + proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult.serializeBinaryToWriter + ); + } +}; + + +/** + * repeated LargePayloadPurgeResult results = 1; + * @return {!Array} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.getResultsList = function() { + return /** @type{!Array} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} returns this +*/ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.setResultsList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 1, value); +}; + + +/** + * @param {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult=} opt_value + * @param {number=} opt_index + * @return {!proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.addResults = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.microsoft.durabletask.largepayloads.LargePayloadPurgeResult, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest} returns this + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsRequest.prototype.clearResultsList = function() { + return this.setResultsList([]); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.prototype.toObject = function(opt_includeInstance) { + return proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.toObject = function(includeInstance, msg) { + var f, obj = { + + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse; + return proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.microsoft.durabletask.largepayloads.ReportLargePayloadPurgeResultsResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; +}; + + +/** + * @enum {number} + */ +proto.microsoft.durabletask.largepayloads.LargePayloadPurgeDisposition = { + LARGE_PAYLOAD_PURGE_DISPOSITION_UNSPECIFIED: 0, + LARGE_PAYLOAD_PURGE_DISPOSITION_DELETED: 1, + LARGE_PAYLOAD_PURGE_DISPOSITION_RETRY: 2, + LARGE_PAYLOAD_PURGE_DISPOSITION_QUARANTINED: 3 +}; + +goog.object.extend(exports, proto.microsoft.durabletask.largepayloads); diff --git a/packages/durabletask-js/test/client-purge.spec.ts b/packages/durabletask-js/test/client-purge.spec.ts index e5a284ca..9ec25140 100644 --- a/packages/durabletask-js/test/client-purge.spec.ts +++ b/packages/durabletask-js/test/client-purge.spec.ts @@ -11,6 +11,7 @@ import { PurgeInstanceCriteria } from "../src/orchestration/orchestration-purge- import { PurgeResult } from "../src/orchestration/orchestration-purge-result"; import * as pb from "../src/proto/orchestrator_service_pb"; import { NoOpLogger } from "../src/types/logger.type"; +import { PayloadStore } from "../src/payloads/payload-store"; type Callback = (error: grpc.ServiceError | null, response?: pb.PurgeInstancesResponse) => void; @@ -72,7 +73,7 @@ describe("TaskHubGrpcClient purge", () => { const request = rpc.mock.calls[0][0]; expect(request.getRecursive()).toBe(true); expect(request.hasInstancebatch()).toBe(false); - expect(request.getIsorchestration()).toBe(false); + expect(request.getIsorchestration()).toBe(path === "single instance"); if (path === "single instance") { expect(request.getInstanceid()).toBe("instance-1"); expect(request.hasPurgeinstancefilter()).toBe(false); @@ -137,4 +138,30 @@ describe("TaskHubGrpcClient purge", () => { expect(cancel).not.toHaveBeenCalled(); callback(null, new pb.PurgeInstancesResponse()); }); + + describe.each([false, true])("payloads enabled=%s", (enabled) => { + it.each(["instance-1", "@counter@key"])("routes purge %s to its backend instance kind", async (id) => { + client["_stub"].close(); + const store = new (class extends PayloadStore { + async upload(): Promise { + return ""; + } + async download(): Promise { + return ""; + } + isKnownPayloadToken(): boolean { + return false; + } + })(); + client = new TaskHubGrpcClient({ payloads: enabled ? { store } : undefined, logger: new NoOpLogger() }); + Object.defineProperty(client["_stub"], "purgeInstances", { value: rpc }); + const result = client.purgeOrchestration(id); + await new Promise((resolve) => setImmediate(resolve)); + expect(rpc).toHaveBeenCalledTimes(1); + const request = rpc.mock.calls[0][0]; + callback(null, new pb.PurgeInstancesResponse()); + await result; + expect(request.getIsorchestration()).toBe(!id.startsWith("@")); + }); + }); }); diff --git a/packages/durabletask-js/test/payload-purge-client.spec.ts b/packages/durabletask-js/test/payload-purge-client.spec.ts new file mode 100644 index 00000000..7514f099 --- /dev/null +++ b/packages/durabletask-js/test/payload-purge-client.spec.ts @@ -0,0 +1,163 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import * as grpc from "@grpc/grpc-js"; +import { TaskHubGrpcClient } from "../src"; +import * as pb from "../src/proto/orchestrator_service_pb"; +import * as stubs from "../src/proto/orchestrator_service_grpc_pb"; +import * as lp from "../src/proto/large_payload_purge_pb"; +import { LargePayloadPurgeService, ILargePayloadPurgeServer } from "../src/proto/large_payload_purge_grpc_pb"; +import { BlobPurgeConstants } from "../src/payloads/purge"; + +describe("large payload auto-purge lifecycle transport", () => { + let server: grpc.Server; + let client: TaskHubGrpcClient; + let calls: string[]; + let start: pb.CreateInstanceRequest | undefined; + let event: pb.RaiseEventRequest | undefined; + let startId: string; + let stateName: string; + let status: pb.OrchestrationStatus; + let collision: boolean; + let hostAddress: string; + let rpcError: grpc.status | undefined; + + beforeEach(async () => { + calls = []; + start = undefined; + event = undefined; + startId = BlobPurgeConstants.instanceId; + stateName = BlobPurgeConstants.orchestrator; + status = pb.OrchestrationStatus.ORCHESTRATION_STATUS_RUNNING; + collision = false; + rpcError = undefined; + server = new grpc.Server(); + const sidecar = { + startInstance: (call, callback) => { + calls.push("start"); + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + start = call.request; + if (collision) callback({ code: grpc.status.ALREADY_EXISTS, message: "exists" }); + else callback(null, new pb.CreateInstanceResponse().setInstanceid(startId)); + }, + waitForInstanceStart: (call, callback) => { + calls.push("wait"); + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + callback( + null, + new pb.GetInstanceResponse() + .setExists(true) + .setOrchestrationstate( + new pb.OrchestrationState() + .setInstanceid(BlobPurgeConstants.instanceId) + .setName(stateName) + .setOrchestrationstatus(status), + ), + ); + }, + raiseEvent: (call, callback) => { + calls.push("event"); + event = call.request; + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + callback(null, new pb.RaiseEventResponse()); + }, + } satisfies Pick; + server.addService(stubs.TaskHubSidecarServiceService, sidecar); + const purge = { + setLargePayloadAutoPurge: (call, callback) => { + calls.push(`setting:${call.request.getEnabled()}`); + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + callback(null, new lp.SetLargePayloadAutoPurgeResponse()); + }, + getLargePayloadTombstones: (call, callback) => { + calls.push("fetch"); + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + expect(Number(call.getDeadline()) - Date.now()).toBeLessThanOrEqual(61000); + if (rpcError !== undefined) callback({ code: rpcError, message: "backend" }); + else + callback( + null, + new lp.GetLargePayloadTombstonesResponse().setTombstonesList([ + new lp.LargePayloadTombstone() + .setTombstoneToken("opaque:\u00e9:do-not-parse") + .setPayloadToken("blob:v2:https://a.invalid/c/b"), + ]), + ); + }, + reportLargePayloadPurgeResults: (call, callback) => { + calls.push("report"); + expect(call.metadata.get("taskhub")).toEqual(["payload-test"]); + expect(Number(call.getDeadline()) - Date.now()).toBeLessThanOrEqual(61000); + expect(call.request.getResultsList()[0].getTombstoneToken()).toBe("opaque:\u00e9:do-not-parse"); + callback(null, new lp.ReportLargePayloadPurgeResultsResponse()); + }, + } satisfies ILargePayloadPurgeServer; + server.addService(LargePayloadPurgeService, purge); + const port = await new Promise((resolve, reject) => + server.bindAsync("127.0.0.1:0", grpc.ServerCredentials.createInsecure(), (error, port) => + error ? reject(error) : resolve(port), + ), + ); + hostAddress = `127.0.0.1:${port}`; + client = new TaskHubGrpcClient({ + hostAddress, + defaultVersion: "business", + metadataGenerator: async () => { + const metadata = new grpc.Metadata(); + metadata.set("taskhub", "payload-test"); + return metadata; + }, + }); + }); + afterEach(async () => { + await client.stop(); + server.forceShutdown(); + }); + + it("writes setting first, schedules unversioned singleton, verifies start and sends configuration", async () => { + await client.setLargePayloadAutoPurge(true, 500); + expect(calls).toEqual(["setting:true", "start", "wait", "event"]); + expect(start!.getInstanceid()).toBe(BlobPurgeConstants.instanceId); + expect(start!.getName()).toBe(BlobPurgeConstants.orchestrator); + expect(start!.getVersion()?.getValue() ?? "").toBe(""); + expect(JSON.parse(start!.getInput()!.getValue())).toEqual({ PurgeBatchSize: 500, PurgedCount: 0 }); + expect(start!.getOrchestrationidreusepolicy()!.getReplaceablestatusList()).toEqual([ + pb.OrchestrationStatus.ORCHESTRATION_STATUS_COMPLETED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_FAILED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_CANCELED, + pb.OrchestrationStatus.ORCHESTRATION_STATUS_TERMINATED, + ]); + expect(event!.getName()).toBe("SetBatchSize"); + expect(event!.getInput()!.getValue()).toBe("500"); + }); + + it("disables without validating batch, starting, waiting, or signaling", async () => { + await client.setLargePayloadAutoPurge(false, NaN); + expect(calls).toEqual(["setting:false"]); + }); + + it.each([0, 1001, NaN, 1.5])("rejects invalid enabling batch %s before mutating the backend", async (batch) => { + await expect(client.setLargePayloadAutoPurge(true, batch)).rejects.toThrow(RangeError); + expect(calls).toEqual([]); + }); + + it("rejects an unexpected backend start ID without waiting or signaling", async () => { + startId = "different"; + await expect(client.setLargePayloadAutoPurge(true)).rejects.toThrow("unexpected"); + expect(calls).toEqual(["setting:true", "start"]); + }); + + it("accepts a deduplicated start only after verifying identity and Running status", async () => { + collision = true; + await client.setLargePayloadAutoPurge(true); + expect(calls).toEqual(["setting:true", "start", "wait", "event"]); + }); + + it.each(["wrong-name", "suspended"])("does not configure a %s reserved-ID collision", async (kind) => { + collision = true; + if (kind === "wrong-name") stateName = "business"; + else status = pb.OrchestrationStatus.ORCHESTRATION_STATUS_SUSPENDED; + await expect(client.setLargePayloadAutoPurge(true)).rejects.toThrow(); + expect(calls).toEqual(["setting:true", "start", "wait"]); + }); +}); diff --git a/tools/generate-grpc-javascript.sh b/tools/generate-grpc-javascript.sh index 4f7979c3..fb488839 100644 --- a/tools/generate-grpc-javascript.sh +++ b/tools/generate-grpc-javascript.sh @@ -27,7 +27,11 @@ generateGrpc() { --js_out="import_style=commonjs,binary:$PATH_PROTO_OUT" \ --ts_out="grpc_js:$PATH_PROTO_OUT" \ --grpc_out="grpc_js:$PATH_PROTO_OUT" \ - ${PROTO_FILE_PATH_ABSOLUTE} + ${PROTO_FILE_PATH_ABSOLUTE} || return $? + + # The TS plugin emits trailing spaces on class declarations. + node -e 'const fs = require("fs"); const file = process.argv[1]; fs.writeFileSync(file, fs.readFileSync(file, "utf8").replace(/[ \t]+$/gm, ""));' \ + "${PATH_PROTO_OUT}/${PROTO_FILE_NAME_NO_PROTO}_pb.d.ts" || return $? echo "- Generated '${PATH_PROTO_OUT}/${PROTO_FILE_NAME_NO_PROTO}_pb.js'" echo "- Generated '${PATH_PROTO_OUT}/${PROTO_FILE_NAME_NO_PROTO}_pb.d.ts'" @@ -39,7 +43,7 @@ fail_trap() { result=$? if [ $result != 0 ]; then - echo "Failed to generate gRPC interface and proto buf: $ret_val" + echo "Failed to generate gRPC interface and proto buf: $result" fi exit $result @@ -79,4 +83,5 @@ fi echo "==============================================" echo "Generating Javascript code in $PATH_PROTO_OUT" -generateGrpc "$PATH_PROTO_SRC/orchestrator_service.proto" \ No newline at end of file +generateGrpc "$PATH_PROTO_SRC/orchestrator_service.proto" || exit $? +generateGrpc "$PATH_PROTO_SRC/large_payload_purge.proto" || exit $? \ No newline at end of file