@azure/event-hubs 6.0.2-alpha.20251014.1 → 6.0.2-alpha.20251021.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/batchingPartitionChannel.d.ts.map +1 -1
- package/dist/browser/batchingPartitionChannel.js +2 -1
- package/dist/browser/batchingPartitionChannel.js.map +1 -1
- package/dist/browser/connectionContext.d.ts.map +1 -1
- package/dist/browser/connectionContext.js +10 -4
- package/dist/browser/connectionContext.js.map +1 -1
- package/dist/browser/eventHubBufferedProducerClient.d.ts.map +1 -1
- package/dist/browser/eventHubBufferedProducerClient.js +2 -1
- package/dist/browser/eventHubBufferedProducerClient.js.map +1 -1
- package/dist/browser/eventHubConsumerClient.d.ts.map +1 -1
- package/dist/browser/eventHubConsumerClient.js +3 -6
- package/dist/browser/eventHubConsumerClient.js.map +1 -1
- package/dist/browser/eventHubProducerClient.d.ts.map +1 -1
- package/dist/browser/eventHubProducerClient.js +3 -6
- package/dist/browser/eventHubProducerClient.js.map +1 -1
- package/dist/browser/eventHubSender.d.ts.map +1 -1
- package/dist/browser/eventHubSender.js +6 -4
- package/dist/browser/eventHubSender.js.map +1 -1
- package/dist/browser/partitionReceiver.js +4 -4
- package/dist/browser/partitionReceiver.js.map +1 -1
- package/dist/browser/util/timerLoop.d.ts.map +1 -1
- package/dist/browser/util/timerLoop.js +12 -5
- package/dist/browser/util/timerLoop.js.map +1 -1
- package/dist/commonjs/batchingPartitionChannel.d.ts.map +1 -1
- package/dist/commonjs/batchingPartitionChannel.js +2 -1
- package/dist/commonjs/batchingPartitionChannel.js.map +1 -1
- package/dist/commonjs/connectionContext.d.ts.map +1 -1
- package/dist/commonjs/connectionContext.js +10 -4
- package/dist/commonjs/connectionContext.js.map +1 -1
- package/dist/commonjs/eventHubBufferedProducerClient.d.ts.map +1 -1
- package/dist/commonjs/eventHubBufferedProducerClient.js +2 -1
- package/dist/commonjs/eventHubBufferedProducerClient.js.map +1 -1
- package/dist/commonjs/eventHubConsumerClient.d.ts.map +1 -1
- package/dist/commonjs/eventHubConsumerClient.js +3 -6
- package/dist/commonjs/eventHubConsumerClient.js.map +1 -1
- package/dist/commonjs/eventHubProducerClient.d.ts.map +1 -1
- package/dist/commonjs/eventHubProducerClient.js +3 -6
- package/dist/commonjs/eventHubProducerClient.js.map +1 -1
- package/dist/commonjs/eventHubSender.d.ts.map +1 -1
- package/dist/commonjs/eventHubSender.js +6 -4
- package/dist/commonjs/eventHubSender.js.map +1 -1
- package/dist/commonjs/partitionReceiver.js +4 -4
- package/dist/commonjs/partitionReceiver.js.map +1 -1
- package/dist/commonjs/util/timerLoop.d.ts.map +1 -1
- package/dist/commonjs/util/timerLoop.js +12 -5
- package/dist/commonjs/util/timerLoop.js.map +1 -1
- package/dist/esm/batchingPartitionChannel.d.ts.map +1 -1
- package/dist/esm/batchingPartitionChannel.js +2 -1
- package/dist/esm/batchingPartitionChannel.js.map +1 -1
- package/dist/esm/connectionContext.d.ts.map +1 -1
- package/dist/esm/connectionContext.js +10 -4
- package/dist/esm/connectionContext.js.map +1 -1
- package/dist/esm/eventHubBufferedProducerClient.d.ts.map +1 -1
- package/dist/esm/eventHubBufferedProducerClient.js +2 -1
- package/dist/esm/eventHubBufferedProducerClient.js.map +1 -1
- package/dist/esm/eventHubConsumerClient.d.ts.map +1 -1
- package/dist/esm/eventHubConsumerClient.js +3 -6
- package/dist/esm/eventHubConsumerClient.js.map +1 -1
- package/dist/esm/eventHubProducerClient.d.ts.map +1 -1
- package/dist/esm/eventHubProducerClient.js +3 -6
- package/dist/esm/eventHubProducerClient.js.map +1 -1
- package/dist/esm/eventHubSender.d.ts.map +1 -1
- package/dist/esm/eventHubSender.js +6 -4
- package/dist/esm/eventHubSender.js.map +1 -1
- package/dist/esm/partitionReceiver.js +4 -4
- package/dist/esm/partitionReceiver.js.map +1 -1
- package/dist/esm/util/timerLoop.d.ts.map +1 -1
- package/dist/esm/util/timerLoop.js +12 -5
- package/dist/esm/util/timerLoop.js.map +1 -1
- package/dist/react-native/batchingPartitionChannel.d.ts +94 -0
- package/dist/react-native/batchingPartitionChannel.d.ts.map +1 -0
- package/dist/react-native/batchingPartitionChannel.js +255 -0
- package/dist/react-native/batchingPartitionChannel.js.map +1 -0
- package/dist/react-native/connectionContext.d.ts +108 -0
- package/dist/react-native/connectionContext.d.ts.map +1 -0
- package/dist/react-native/connectionContext.js +310 -0
- package/dist/react-native/connectionContext.js.map +1 -0
- package/dist/react-native/dataTransformer.d.ts +53 -0
- package/dist/react-native/dataTransformer.d.ts.map +1 -0
- package/dist/react-native/dataTransformer.js +133 -0
- package/dist/react-native/dataTransformer.js.map +1 -0
- package/dist/react-native/diagnostics/instrumentEventData.d.ts +28 -0
- package/dist/react-native/diagnostics/instrumentEventData.d.ts.map +1 -0
- package/dist/react-native/diagnostics/instrumentEventData.js +67 -0
- package/dist/react-native/diagnostics/instrumentEventData.js.map +1 -0
- package/dist/react-native/diagnostics/tracing.d.ts +19 -0
- package/dist/react-native/diagnostics/tracing.d.ts.map +1 -0
- package/dist/react-native/diagnostics/tracing.js +40 -0
- package/dist/react-native/diagnostics/tracing.js.map +1 -0
- package/dist/react-native/eventData.d.ts +295 -0
- package/dist/react-native/eventData.d.ts.map +1 -0
- package/dist/react-native/eventData.js +247 -0
- package/dist/react-native/eventData.js.map +1 -0
- package/dist/react-native/eventDataAdapter.d.ts +69 -0
- package/dist/react-native/eventDataAdapter.d.ts.map +1 -0
- package/dist/react-native/eventDataAdapter.js +38 -0
- package/dist/react-native/eventDataAdapter.js.map +1 -0
- package/dist/react-native/eventDataBatch.d.ts +225 -0
- package/dist/react-native/eventDataBatch.d.ts.map +1 -0
- package/dist/react-native/eventDataBatch.js +301 -0
- package/dist/react-native/eventDataBatch.js.map +1 -0
- package/dist/react-native/eventHubBufferedProducerClient.d.ts +323 -0
- package/dist/react-native/eventHubBufferedProducerClient.d.ts.map +1 -0
- package/dist/react-native/eventHubBufferedProducerClient.js +301 -0
- package/dist/react-native/eventHubBufferedProducerClient.js.map +1 -0
- package/dist/react-native/eventHubConsumerClient.d.ts +293 -0
- package/dist/react-native/eventHubConsumerClient.d.ts.map +1 -0
- package/dist/react-native/eventHubConsumerClient.js +336 -0
- package/dist/react-native/eventHubConsumerClient.js.map +1 -0
- package/dist/react-native/eventHubConsumerClientModels.d.ts +218 -0
- package/dist/react-native/eventHubConsumerClientModels.d.ts.map +1 -0
- package/dist/react-native/eventHubConsumerClientModels.js +4 -0
- package/dist/react-native/eventHubConsumerClientModels.js.map +1 -0
- package/dist/react-native/eventHubProducerClient.d.ts +299 -0
- package/dist/react-native/eventHubProducerClient.d.ts.map +1 -0
- package/dist/react-native/eventHubProducerClient.js +366 -0
- package/dist/react-native/eventHubProducerClient.js.map +1 -0
- package/dist/react-native/eventHubSender.d.ts +227 -0
- package/dist/react-native/eventHubSender.d.ts.map +1 -0
- package/dist/react-native/eventHubSender.js +626 -0
- package/dist/react-native/eventHubSender.js.map +1 -0
- package/dist/react-native/eventPosition.d.ts +73 -0
- package/dist/react-native/eventPosition.d.ts.map +1 -0
- package/dist/react-native/eventPosition.js +121 -0
- package/dist/react-native/eventPosition.js.map +1 -0
- package/dist/react-native/eventProcessor.d.ts +232 -0
- package/dist/react-native/eventProcessor.d.ts.map +1 -0
- package/dist/react-native/eventProcessor.js +389 -0
- package/dist/react-native/eventProcessor.js.map +1 -0
- package/dist/react-native/eventhubConnectionConfig.d.ts +96 -0
- package/dist/react-native/eventhubConnectionConfig.d.ts.map +1 -0
- package/dist/react-native/eventhubConnectionConfig.js +98 -0
- package/dist/react-native/eventhubConnectionConfig.js.map +1 -0
- package/dist/react-native/impl/awaitableQueue.d.ts +25 -0
- package/dist/react-native/impl/awaitableQueue.d.ts.map +1 -0
- package/dist/react-native/impl/awaitableQueue.js +51 -0
- package/dist/react-native/impl/awaitableQueue.js.map +1 -0
- package/dist/react-native/impl/partitionAssigner.d.ts +29 -0
- package/dist/react-native/impl/partitionAssigner.d.ts.map +1 -0
- package/dist/react-native/impl/partitionAssigner.js +52 -0
- package/dist/react-native/impl/partitionAssigner.js.map +1 -0
- package/dist/react-native/impl/partitionGate.d.ts +27 -0
- package/dist/react-native/impl/partitionGate.d.ts.map +1 -0
- package/dist/react-native/impl/partitionGate.js +38 -0
- package/dist/react-native/impl/partitionGate.js.map +1 -0
- package/dist/react-native/impl/partitionKeyToIdMapper.d.ts +6 -0
- package/dist/react-native/impl/partitionKeyToIdMapper.d.ts.map +1 -0
- package/dist/react-native/impl/partitionKeyToIdMapper.js +111 -0
- package/dist/react-native/impl/partitionKeyToIdMapper.js.map +1 -0
- package/dist/react-native/inMemoryCheckpointStore.d.ts +44 -0
- package/dist/react-native/inMemoryCheckpointStore.d.ts.map +1 -0
- package/dist/react-native/inMemoryCheckpointStore.js +94 -0
- package/dist/react-native/inMemoryCheckpointStore.js.map +1 -0
- package/dist/react-native/index.d.ts +21 -0
- package/dist/react-native/index.d.ts.map +1 -0
- package/dist/react-native/index.js +12 -0
- package/dist/react-native/index.js.map +1 -0
- package/dist/react-native/loadBalancerStrategies/balancedStrategy.d.ts +30 -0
- package/dist/react-native/loadBalancerStrategies/balancedStrategy.d.ts.map +1 -0
- package/dist/react-native/loadBalancerStrategies/balancedStrategy.js +40 -0
- package/dist/react-native/loadBalancerStrategies/balancedStrategy.js.map +1 -0
- package/dist/react-native/loadBalancerStrategies/greedyStrategy.d.ts +24 -0
- package/dist/react-native/loadBalancerStrategies/greedyStrategy.d.ts.map +1 -0
- package/dist/react-native/loadBalancerStrategies/greedyStrategy.js +29 -0
- package/dist/react-native/loadBalancerStrategies/greedyStrategy.js.map +1 -0
- package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.d.ts +28 -0
- package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.d.ts.map +1 -0
- package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.js +245 -0
- package/dist/react-native/loadBalancerStrategies/loadBalancingStrategy.js.map +1 -0
- package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.d.ts +20 -0
- package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.d.ts.map +1 -0
- package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.js +22 -0
- package/dist/react-native/loadBalancerStrategies/unbalancedStrategy.js.map +1 -0
- package/dist/react-native/logger.d.ts +37 -0
- package/dist/react-native/logger.d.ts.map +1 -0
- package/dist/react-native/logger.js +56 -0
- package/dist/react-native/logger.js.map +1 -0
- package/dist/react-native/managementClient.d.ts +145 -0
- package/dist/react-native/managementClient.d.ts.map +1 -0
- package/dist/react-native/managementClient.js +305 -0
- package/dist/react-native/managementClient.js.map +1 -0
- package/dist/react-native/models/private.d.ts +185 -0
- package/dist/react-native/models/private.d.ts.map +1 -0
- package/dist/react-native/models/private.js +4 -0
- package/dist/react-native/models/private.js.map +1 -0
- package/dist/react-native/models/public.d.ts +240 -0
- package/dist/react-native/models/public.d.ts.map +1 -0
- package/dist/react-native/models/public.js +18 -0
- package/dist/react-native/models/public.js.map +1 -0
- package/dist/react-native/package.json +3 -0
- package/dist/react-native/partitionProcessor.d.ts +134 -0
- package/dist/react-native/partitionProcessor.d.ts.map +1 -0
- package/dist/react-native/partitionProcessor.js +137 -0
- package/dist/react-native/partitionProcessor.js.map +1 -0
- package/dist/react-native/partitionPump.d.ts +38 -0
- package/dist/react-native/partitionPump.d.ts.map +1 -0
- package/dist/react-native/partitionPump.js +175 -0
- package/dist/react-native/partitionPump.js.map +1 -0
- package/dist/react-native/partitionReceiver.d.ts +82 -0
- package/dist/react-native/partitionReceiver.d.ts.map +1 -0
- package/dist/react-native/partitionReceiver.js +335 -0
- package/dist/react-native/partitionReceiver.js.map +1 -0
- package/dist/react-native/pumpManager.d.ts +72 -0
- package/dist/react-native/pumpManager.d.ts.map +1 -0
- package/dist/react-native/pumpManager.js +120 -0
- package/dist/react-native/pumpManager.js.map +1 -0
- package/dist/react-native/util/connectionStringUtils.d.ts +52 -0
- package/dist/react-native/util/connectionStringUtils.d.ts.map +1 -0
- package/dist/react-native/util/connectionStringUtils.js +48 -0
- package/dist/react-native/util/connectionStringUtils.js.map +1 -0
- package/dist/react-native/util/constants.d.ts +25 -0
- package/dist/react-native/util/constants.d.ts.map +1 -0
- package/dist/react-native/util/constants.js +27 -0
- package/dist/react-native/util/constants.js.map +1 -0
- package/dist/react-native/util/delayWithoutThrow.d.ts +8 -0
- package/dist/react-native/util/delayWithoutThrow.d.ts.map +1 -0
- package/dist/react-native/util/delayWithoutThrow.js +17 -0
- package/dist/react-native/util/delayWithoutThrow.js.map +1 -0
- package/dist/react-native/util/error.d.ts +39 -0
- package/dist/react-native/util/error.d.ts.map +1 -0
- package/dist/react-native/util/error.js +103 -0
- package/dist/react-native/util/error.js.map +1 -0
- package/dist/react-native/util/getPromiseParts.d.ts +10 -0
- package/dist/react-native/util/getPromiseParts.d.ts.map +1 -0
- package/dist/react-native/util/getPromiseParts.js +20 -0
- package/dist/react-native/util/getPromiseParts.js.map +1 -0
- package/dist/react-native/util/operationOptions.d.ts +16 -0
- package/dist/react-native/util/operationOptions.d.ts.map +1 -0
- package/dist/react-native/util/operationOptions.js +4 -0
- package/dist/react-native/util/operationOptions.js.map +1 -0
- package/dist/react-native/util/parseEndpoint.d.ts +11 -0
- package/dist/react-native/util/parseEndpoint.d.ts.map +1 -0
- package/dist/react-native/util/parseEndpoint.js +17 -0
- package/dist/react-native/util/parseEndpoint.js.map +1 -0
- package/dist/react-native/util/retries.d.ts +6 -0
- package/dist/react-native/util/retries.d.ts.map +1 -0
- package/dist/react-native/util/retries.js +13 -0
- package/dist/react-native/util/retries.js.map +1 -0
- package/dist/react-native/util/runtimeInfo-react-native.d.mts.map +1 -0
- package/dist/react-native/util/runtimeInfo-react-native.mjs.map +1 -0
- package/dist/react-native/util/runtimeInfo.d.ts +6 -0
- package/dist/react-native/util/runtimeInfo.js +20 -0
- package/dist/react-native/util/timerLoop.d.ts +26 -0
- package/dist/react-native/util/timerLoop.d.ts.map +1 -0
- package/dist/react-native/util/timerLoop.js +34 -0
- package/dist/react-native/util/timerLoop.js.map +1 -0
- package/dist/react-native/util/typeGuards.d.ts +8 -0
- package/dist/react-native/util/typeGuards.d.ts.map +1 -0
- package/dist/react-native/util/typeGuards.js +12 -0
- package/dist/react-native/util/typeGuards.js.map +1 -0
- package/dist/react-native/util/utils.d.ts +7 -0
- package/dist/react-native/util/utils.d.ts.map +1 -0
- package/dist/react-native/util/utils.js +13 -0
- package/dist/react-native/util/utils.js.map +1 -0
- package/dist/react-native/withAuth.d.ts +25 -0
- package/dist/react-native/withAuth.d.ts.map +1 -0
- package/dist/react-native/withAuth.js +84 -0
- package/dist/react-native/withAuth.js.map +1 -0
- package/package.json +16 -11
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
import { logErrorStackTrace, logger } from "./logger.js";
|
|
4
|
+
import { CloseReason } from "./models/public.js";
|
|
5
|
+
import { createReceiver } from "./partitionReceiver.js";
|
|
6
|
+
import { toSpanOptions, tracingClient } from "./diagnostics/tracing.js";
|
|
7
|
+
import { extractSpanContextFromEventData } from "./diagnostics/instrumentEventData.js";
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export class PartitionPump {
|
|
12
|
+
_context;
|
|
13
|
+
_startPosition;
|
|
14
|
+
_partitionProcessor;
|
|
15
|
+
_processorOptions;
|
|
16
|
+
_receiver;
|
|
17
|
+
_isReceiving = false;
|
|
18
|
+
_isStopped = false;
|
|
19
|
+
_abortController;
|
|
20
|
+
constructor(_context, partitionProcessor, _startPosition, options) {
|
|
21
|
+
this._context = _context;
|
|
22
|
+
this._startPosition = _startPosition;
|
|
23
|
+
this._partitionProcessor = partitionProcessor;
|
|
24
|
+
this._processorOptions = options;
|
|
25
|
+
this._abortController = new AbortController();
|
|
26
|
+
}
|
|
27
|
+
get isReceiving() {
|
|
28
|
+
return this._isReceiving;
|
|
29
|
+
}
|
|
30
|
+
async start() {
|
|
31
|
+
this._isReceiving = true;
|
|
32
|
+
try {
|
|
33
|
+
await this._partitionProcessor.initialize();
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
// swallow the error from the user-defined code
|
|
37
|
+
this._partitionProcessor.processError(err);
|
|
38
|
+
}
|
|
39
|
+
// this is intentionally not await'd - the _receiveEvents loop will continue to
|
|
40
|
+
// execute and can be stopped by calling .stop()
|
|
41
|
+
this._receiveEvents(this._partitionProcessor.partitionId);
|
|
42
|
+
logger.info(`Successfully started the receiver for partition "${this._partitionProcessor.partitionId}".`);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a new `PartitionReceiver` and replaces any existing receiver.
|
|
46
|
+
* @param partitionId - The partition the receiver should read messages from.
|
|
47
|
+
* @param lastSeenSequenceNumber - The sequence number to begin receiving messages from (exclusive).
|
|
48
|
+
* If `-1`, then the PartitionPump's startPosition will be used instead.
|
|
49
|
+
*/
|
|
50
|
+
_setOrReplaceReceiver(partitionId, lastSeenSequenceNumber) {
|
|
51
|
+
// Determine what the new EventPosition should be.
|
|
52
|
+
// If this PartitionPump has received events, we'll start from the last
|
|
53
|
+
// seen sequenceNumber (exclusive).
|
|
54
|
+
// Otherwise, use the `_startPosition`.
|
|
55
|
+
const currentEventPosition = lastSeenSequenceNumber >= 0
|
|
56
|
+
? {
|
|
57
|
+
sequenceNumber: lastSeenSequenceNumber,
|
|
58
|
+
isInclusive: false,
|
|
59
|
+
}
|
|
60
|
+
: this._startPosition;
|
|
61
|
+
// Set or replace the PartitionPump's receiver.
|
|
62
|
+
this._receiver = createReceiver(this._context, this._partitionProcessor.consumerGroup, this._partitionProcessor.eventProcessorId, partitionId, currentEventPosition, {
|
|
63
|
+
ownerLevel: this._processorOptions.ownerLevel,
|
|
64
|
+
trackLastEnqueuedEventProperties: this._processorOptions.trackLastEnqueuedEventProperties,
|
|
65
|
+
retryOptions: this._processorOptions.retryOptions,
|
|
66
|
+
skipParsingBodyAsJson: this._processorOptions.skipParsingBodyAsJson,
|
|
67
|
+
prefetchCount: this._processorOptions.prefetchCount,
|
|
68
|
+
});
|
|
69
|
+
return this._receiver;
|
|
70
|
+
}
|
|
71
|
+
async _receiveEvents(partitionId) {
|
|
72
|
+
let lastSeenSequenceNumber = -1;
|
|
73
|
+
let receiver = this._setOrReplaceReceiver(partitionId, lastSeenSequenceNumber);
|
|
74
|
+
while (this._isReceiving) {
|
|
75
|
+
try {
|
|
76
|
+
// Check if the receiver was closed so we can recreate it.
|
|
77
|
+
if (receiver.isClosed) {
|
|
78
|
+
receiver = this._setOrReplaceReceiver(partitionId, lastSeenSequenceNumber);
|
|
79
|
+
}
|
|
80
|
+
const receivedEvents = await receiver.receiveBatch(this._processorOptions.maxBatchSize, this._processorOptions.maxWaitTimeInSeconds, this._abortController.signal);
|
|
81
|
+
if (this._processorOptions.trackLastEnqueuedEventProperties &&
|
|
82
|
+
receiver.lastEnqueuedEventProperties) {
|
|
83
|
+
this._partitionProcessor.lastEnqueuedEventProperties =
|
|
84
|
+
receiver.lastEnqueuedEventProperties;
|
|
85
|
+
}
|
|
86
|
+
// avoid calling user's processEvents handler if the pump was stopped while receiving events
|
|
87
|
+
if (!this._isReceiving) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (receivedEvents.length) {
|
|
91
|
+
lastSeenSequenceNumber = receivedEvents[receivedEvents.length - 1].sequenceNumber;
|
|
92
|
+
}
|
|
93
|
+
await tracingClient.withSpan("PartitionPump.process", {}, () => this._partitionProcessor.processEvents(receivedEvents), toProcessingSpanOptions(receivedEvents, this._context.config));
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
// check if this pump is still receiving
|
|
97
|
+
// it may not be if the EventProcessor was stopped during processEvents
|
|
98
|
+
if (!this._isReceiving) {
|
|
99
|
+
// no longer receiving, so close was called from somewhere else
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
logger.warning(`An error was thrown while receiving or processing events on partition "${this._partitionProcessor.partitionId}"`);
|
|
103
|
+
logErrorStackTrace(err);
|
|
104
|
+
// forward error to user's processError and swallow errors they may throw
|
|
105
|
+
try {
|
|
106
|
+
await this._partitionProcessor.processError(err);
|
|
107
|
+
}
|
|
108
|
+
catch (errorFromUser) {
|
|
109
|
+
// Using verbose over warning because this error is swallowed.
|
|
110
|
+
logger.verbose("An error was thrown by user's processError method: ", errorFromUser);
|
|
111
|
+
}
|
|
112
|
+
// close the partition processor if a non-retryable error was encountered
|
|
113
|
+
if (typeof err !== "object" || !err.retryable) {
|
|
114
|
+
try {
|
|
115
|
+
// If the exception indicates that the partition was stolen (i.e some other consumer with same ownerlevel
|
|
116
|
+
// started consuming the partition), update the closeReason
|
|
117
|
+
if (err.code === "ReceiverDisconnectedError") {
|
|
118
|
+
return await this.stop(CloseReason.OwnershipLost);
|
|
119
|
+
}
|
|
120
|
+
// this will close the pump and will break us out of the while loop
|
|
121
|
+
return await this.stop(CloseReason.Shutdown);
|
|
122
|
+
}
|
|
123
|
+
catch (errorFromStop) {
|
|
124
|
+
// Using verbose over warning because this error is swallowed.
|
|
125
|
+
logger.verbose(`An error occurred while closing the receiver with reason ${CloseReason.Shutdown}: `, errorFromStop);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async stop(reason) {
|
|
132
|
+
if (this._isStopped) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this._isStopped = true;
|
|
136
|
+
this._isReceiving = false;
|
|
137
|
+
try {
|
|
138
|
+
// Trigger the cancellation before closing the receiver,
|
|
139
|
+
// otherwise the receiver will remove the listener on the abortSignal
|
|
140
|
+
// before it has a chance to be emitted.
|
|
141
|
+
this._abortController.abort();
|
|
142
|
+
await this._receiver?.close();
|
|
143
|
+
await this._partitionProcessor.close(reason);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
logger.warning(`An error occurred while closing the receiver: ${err?.name}: ${err?.message}`);
|
|
147
|
+
logErrorStackTrace(err);
|
|
148
|
+
this._partitionProcessor.processError(err);
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
export function toProcessingSpanOptions(receivedEvents, eventHubProperties) {
|
|
157
|
+
const spanLinks = [];
|
|
158
|
+
for (const receivedEvent of receivedEvents) {
|
|
159
|
+
const tracingContext = extractSpanContextFromEventData(receivedEvent);
|
|
160
|
+
if (tracingContext) {
|
|
161
|
+
spanLinks.push({
|
|
162
|
+
tracingContext,
|
|
163
|
+
attributes: {
|
|
164
|
+
enqueuedTime: receivedEvent.enqueuedTimeUtc.getTime(),
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
spanLinks,
|
|
171
|
+
spanKind: "consumer",
|
|
172
|
+
...toSpanOptions(eventHubProperties, "process"),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=partitionPump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partitionPump.js","sourceRoot":"","sources":["../../src/partitionPump.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { TracingSpanOptions, TracingSpanLink } from \"@azure/core-tracing\";\nimport { logErrorStackTrace, logger } from \"./logger.js\";\nimport { CloseReason } from \"./models/public.js\";\nimport type { CommonEventProcessorOptions } from \"./models/private.js\";\nimport type { ConnectionContext } from \"./connectionContext.js\";\nimport type { EventHubConnectionConfig } from \"./eventhubConnectionConfig.js\";\nimport type { PartitionReceiver } from \"./partitionReceiver.js\";\nimport { createReceiver } from \"./partitionReceiver.js\";\nimport type { EventPosition } from \"./eventPosition.js\";\nimport type { MessagingError } from \"@azure/core-amqp\";\nimport type { PartitionProcessor } from \"./partitionProcessor.js\";\nimport type { ReceivedEventData } from \"./eventData.js\";\nimport { toSpanOptions, tracingClient } from \"./diagnostics/tracing.js\";\nimport { extractSpanContextFromEventData } from \"./diagnostics/instrumentEventData.js\";\n\n/**\n * @internal\n */\nexport class PartitionPump {\n private _partitionProcessor: PartitionProcessor;\n private _processorOptions: CommonEventProcessorOptions;\n private _receiver: PartitionReceiver | undefined;\n private _isReceiving: boolean = false;\n private _isStopped: boolean = false;\n private _abortController: AbortController;\n constructor(\n private _context: ConnectionContext,\n partitionProcessor: PartitionProcessor,\n private readonly _startPosition: EventPosition,\n options: CommonEventProcessorOptions,\n ) {\n this._partitionProcessor = partitionProcessor;\n this._processorOptions = options;\n this._abortController = new AbortController();\n }\n\n public get isReceiving(): boolean {\n return this._isReceiving;\n }\n\n async start(): Promise<void> {\n this._isReceiving = true;\n try {\n await this._partitionProcessor.initialize();\n } catch (err) {\n // swallow the error from the user-defined code\n this._partitionProcessor.processError(err as Error);\n }\n\n // this is intentionally not await'd - the _receiveEvents loop will continue to\n // execute and can be stopped by calling .stop()\n this._receiveEvents(this._partitionProcessor.partitionId);\n logger.info(\n `Successfully started the receiver for partition \"${this._partitionProcessor.partitionId}\".`,\n );\n }\n\n /**\n * Creates a new `PartitionReceiver` and replaces any existing receiver.\n * @param partitionId - The partition the receiver should read messages from.\n * @param lastSeenSequenceNumber - The sequence number to begin receiving messages from (exclusive).\n * If `-1`, then the PartitionPump's startPosition will be used instead.\n */\n private _setOrReplaceReceiver(\n partitionId: string,\n lastSeenSequenceNumber: number,\n ): PartitionReceiver {\n // Determine what the new EventPosition should be.\n // If this PartitionPump has received events, we'll start from the last\n // seen sequenceNumber (exclusive).\n // Otherwise, use the `_startPosition`.\n const currentEventPosition: EventPosition =\n lastSeenSequenceNumber >= 0\n ? {\n sequenceNumber: lastSeenSequenceNumber,\n isInclusive: false,\n }\n : this._startPosition;\n\n // Set or replace the PartitionPump's receiver.\n this._receiver = createReceiver(\n this._context,\n this._partitionProcessor.consumerGroup,\n this._partitionProcessor.eventProcessorId,\n partitionId,\n currentEventPosition,\n {\n ownerLevel: this._processorOptions.ownerLevel,\n trackLastEnqueuedEventProperties: this._processorOptions.trackLastEnqueuedEventProperties,\n retryOptions: this._processorOptions.retryOptions,\n skipParsingBodyAsJson: this._processorOptions.skipParsingBodyAsJson,\n prefetchCount: this._processorOptions.prefetchCount,\n },\n );\n\n return this._receiver;\n }\n\n private async _receiveEvents(partitionId: string): Promise<void> {\n let lastSeenSequenceNumber = -1;\n let receiver = this._setOrReplaceReceiver(partitionId, lastSeenSequenceNumber);\n\n while (this._isReceiving) {\n try {\n // Check if the receiver was closed so we can recreate it.\n if (receiver.isClosed) {\n receiver = this._setOrReplaceReceiver(partitionId, lastSeenSequenceNumber);\n }\n\n const receivedEvents = await receiver.receiveBatch(\n this._processorOptions.maxBatchSize,\n this._processorOptions.maxWaitTimeInSeconds,\n this._abortController.signal,\n );\n\n if (\n this._processorOptions.trackLastEnqueuedEventProperties &&\n receiver.lastEnqueuedEventProperties\n ) {\n this._partitionProcessor.lastEnqueuedEventProperties =\n receiver.lastEnqueuedEventProperties;\n }\n // avoid calling user's processEvents handler if the pump was stopped while receiving events\n if (!this._isReceiving) {\n return;\n }\n\n if (receivedEvents.length) {\n lastSeenSequenceNumber = receivedEvents[receivedEvents.length - 1].sequenceNumber;\n }\n\n await tracingClient.withSpan(\n \"PartitionPump.process\",\n {},\n () => this._partitionProcessor.processEvents(receivedEvents),\n toProcessingSpanOptions(receivedEvents, this._context.config),\n );\n } catch (err: any) {\n // check if this pump is still receiving\n // it may not be if the EventProcessor was stopped during processEvents\n if (!this._isReceiving) {\n // no longer receiving, so close was called from somewhere else\n return;\n }\n\n logger.warning(\n `An error was thrown while receiving or processing events on partition \"${this._partitionProcessor.partitionId}\"`,\n );\n logErrorStackTrace(err);\n // forward error to user's processError and swallow errors they may throw\n try {\n await this._partitionProcessor.processError(err as Error);\n } catch (errorFromUser) {\n // Using verbose over warning because this error is swallowed.\n logger.verbose(\"An error was thrown by user's processError method: \", errorFromUser);\n }\n\n // close the partition processor if a non-retryable error was encountered\n if (typeof err !== \"object\" || !(err as MessagingError).retryable) {\n try {\n // If the exception indicates that the partition was stolen (i.e some other consumer with same ownerlevel\n // started consuming the partition), update the closeReason\n if (err.code === \"ReceiverDisconnectedError\") {\n return await this.stop(CloseReason.OwnershipLost);\n }\n // this will close the pump and will break us out of the while loop\n return await this.stop(CloseReason.Shutdown);\n } catch (errorFromStop) {\n // Using verbose over warning because this error is swallowed.\n logger.verbose(\n `An error occurred while closing the receiver with reason ${CloseReason.Shutdown}: `,\n errorFromStop,\n );\n }\n }\n }\n }\n }\n\n async stop(reason: CloseReason): Promise<void> {\n if (this._isStopped) {\n return;\n }\n this._isStopped = true;\n this._isReceiving = false;\n try {\n // Trigger the cancellation before closing the receiver,\n // otherwise the receiver will remove the listener on the abortSignal\n // before it has a chance to be emitted.\n this._abortController.abort();\n await this._receiver?.close();\n await this._partitionProcessor.close(reason);\n } catch (err: any) {\n logger.warning(`An error occurred while closing the receiver: ${err?.name}: ${err?.message}`);\n logErrorStackTrace(err);\n this._partitionProcessor.processError(err);\n throw err;\n }\n }\n}\n\n/**\n * @internal\n */\nexport function toProcessingSpanOptions(\n receivedEvents: ReceivedEventData[],\n eventHubProperties: Pick<EventHubConnectionConfig, \"entityPath\" | \"host\">,\n): TracingSpanOptions {\n const spanLinks: TracingSpanLink[] = [];\n for (const receivedEvent of receivedEvents) {\n const tracingContext = extractSpanContextFromEventData(receivedEvent);\n if (tracingContext) {\n spanLinks.push({\n tracingContext,\n attributes: {\n enqueuedTime: receivedEvent.enqueuedTimeUtc.getTime(),\n },\n });\n }\n }\n return {\n spanLinks,\n spanKind: \"consumer\",\n ...toSpanOptions(eventHubProperties, \"process\"),\n };\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { AbortSignalLike } from "@azure/abort-controller";
|
|
2
|
+
import type { MessagingError } from "@azure/core-amqp";
|
|
3
|
+
import type { ReceivedEventData } from "./eventData.js";
|
|
4
|
+
import type { EventPosition } from "./eventPosition.js";
|
|
5
|
+
import type { ConnectionContext } from "./connectionContext.js";
|
|
6
|
+
import type { PartitionReceiverOptions } from "./models/private.js";
|
|
7
|
+
type Writable<T> = {
|
|
8
|
+
-readonly [P in keyof T]: T[P];
|
|
9
|
+
};
|
|
10
|
+
/** @internal */
|
|
11
|
+
export type WritableReceiver = Writable<PartitionReceiver>;
|
|
12
|
+
/**
|
|
13
|
+
* A set of information about the last enqueued event of a partition, as observed by the consumer as
|
|
14
|
+
* events are received from the Event Hubs service
|
|
15
|
+
*/
|
|
16
|
+
export interface LastEnqueuedEventProperties {
|
|
17
|
+
/**
|
|
18
|
+
* The sequence number of the event that was last enqueued into the Event Hub partition from which
|
|
19
|
+
* this event was received.
|
|
20
|
+
*/
|
|
21
|
+
sequenceNumber?: number;
|
|
22
|
+
/**
|
|
23
|
+
* The date and time, in UTC, that the last event was enqueued into the Event Hub partition from
|
|
24
|
+
* which this event was received.
|
|
25
|
+
*/
|
|
26
|
+
enqueuedOn?: Date;
|
|
27
|
+
/**
|
|
28
|
+
* The offset of the event that was last enqueued into the Event Hub partition from which
|
|
29
|
+
* this event was received.
|
|
30
|
+
*/
|
|
31
|
+
offset?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The date and time, in UTC, that the last event was retrieved from the Event Hub partition.
|
|
34
|
+
*/
|
|
35
|
+
retrievedOn?: Date;
|
|
36
|
+
}
|
|
37
|
+
/** @internal */
|
|
38
|
+
export interface PartitionReceiver {
|
|
39
|
+
readonly checkpoint: number;
|
|
40
|
+
readonly lastEnqueuedEventProperties: LastEnqueuedEventProperties;
|
|
41
|
+
readonly isClosed: boolean;
|
|
42
|
+
readonly close: () => Promise<void>;
|
|
43
|
+
readonly abort: () => Promise<void>;
|
|
44
|
+
readonly isOpen: () => boolean;
|
|
45
|
+
readonly receiveBatch: (maxMessageCount: number, maxWaitTimeInSeconds?: number, abortSignal?: AbortSignalLike) => Promise<ReceivedEventData[]>;
|
|
46
|
+
/** Needed for tests only */
|
|
47
|
+
readonly _onError?: (error: MessagingError | Error) => void;
|
|
48
|
+
readonly connect: (options: ConnectOptions) => Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
interface ConnectOptions {
|
|
51
|
+
abortSignal: AbortSignalLike | undefined;
|
|
52
|
+
timeoutInMs: number;
|
|
53
|
+
}
|
|
54
|
+
/** @internal */
|
|
55
|
+
export declare function createReceiver(ctx: ConnectionContext, consumerGroup: string, consumerId: string, partitionId: string, eventPosition: EventPosition, options?: PartitionReceiverOptions): PartitionReceiver;
|
|
56
|
+
/**
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export declare function checkOnInterval(waitTimeInMs: number, check: () => boolean, options?: {
|
|
60
|
+
abortSignal?: AbortSignalLike;
|
|
61
|
+
cleanupBeforeAbort?: () => void;
|
|
62
|
+
abortErrorMsg?: string;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Returns a promise that will resolve when it is time to read from the queue
|
|
66
|
+
* @param maxEventCount - The maximum number of events to receive.
|
|
67
|
+
* @param maxWaitTimeInMs - The maximum time to wait in ms for the queue to contain any events.
|
|
68
|
+
* @param readIntervalWaitTimeInMs - The time interval to wait in ms before checking the queue.
|
|
69
|
+
* @param queue - The queue to read from.
|
|
70
|
+
* @param options - The options bag.
|
|
71
|
+
* @returns a promise that will resolve when it is time to read from the queue
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
export declare function waitForEvents(maxEventCount: number, maxWaitTimeInMs: number, readIntervalWaitTimeInMs: number, queue: unknown[], options?: {
|
|
75
|
+
abortSignal?: AbortSignalLike;
|
|
76
|
+
cleanupBeforeAbort?: () => void;
|
|
77
|
+
receivedAfterWait?: () => void;
|
|
78
|
+
receivedAlready?: () => void;
|
|
79
|
+
receivedNone?: () => void;
|
|
80
|
+
}): Promise<void>;
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=partitionReceiver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partitionReceiver.d.ts","sourceRoot":"","sources":["../../src/partitionReceiver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
import { AbortError } from "@azure/abort-controller";
|
|
4
|
+
import { Constants, RetryOperationType, StandardAbortMessage, retry, translate, } from "@azure/core-amqp";
|
|
5
|
+
import { types } from "rhea-promise";
|
|
6
|
+
import { fromRheaMessage } from "./eventData.js";
|
|
7
|
+
import { getEventPositionFilter } from "./eventPosition.js";
|
|
8
|
+
import { createSimpleLogger, logErrorStackTrace, logObj, logger as azureLogger, createReceiverLogPrefix, } from "./logger.js";
|
|
9
|
+
import { getRetryAttemptTimeoutInMs } from "./util/retries.js";
|
|
10
|
+
import { createAbortablePromise } from "@azure/core-util";
|
|
11
|
+
import { getRandomName } from "./util/utils.js";
|
|
12
|
+
import { withAuth } from "./withAuth.js";
|
|
13
|
+
import { geoReplication, receiverIdPropertyName } from "./util/constants.js";
|
|
14
|
+
const abortLogMessage = "operation has been cancelled by the user";
|
|
15
|
+
/** The time to wait in ms before attempting to read from the queue */
|
|
16
|
+
const qReadIntervalInMs = 20;
|
|
17
|
+
/** @internal */
|
|
18
|
+
export function createReceiver(ctx, consumerGroup, consumerId, partitionId, eventPosition, options = {}) {
|
|
19
|
+
const address = ctx.config.getReceiverAddress(partitionId, consumerGroup);
|
|
20
|
+
const name = getRandomName(address);
|
|
21
|
+
const audience = ctx.config.getReceiverAudience(partitionId, consumerGroup);
|
|
22
|
+
const logPrefix = createReceiverLogPrefix(consumerId, ctx.connectionId, partitionId);
|
|
23
|
+
const logger = createSimpleLogger(azureLogger, logPrefix);
|
|
24
|
+
const queue = [];
|
|
25
|
+
const state = {
|
|
26
|
+
isConnecting: false,
|
|
27
|
+
};
|
|
28
|
+
const obj = {
|
|
29
|
+
_onError: undefined,
|
|
30
|
+
checkpoint: -1,
|
|
31
|
+
lastEnqueuedEventProperties: {},
|
|
32
|
+
isClosed: false,
|
|
33
|
+
close: async () => {
|
|
34
|
+
clearHandlers(obj);
|
|
35
|
+
delete ctx.receivers[name];
|
|
36
|
+
logger.verbose("deleted the receiver from the client cache");
|
|
37
|
+
state.authLoop?.stop();
|
|
38
|
+
return state.link
|
|
39
|
+
?.close()
|
|
40
|
+
.catch((err) => {
|
|
41
|
+
logger.warning(`an error occurred while closing: ${err?.name}: ${err?.message}`);
|
|
42
|
+
logErrorStackTrace(err);
|
|
43
|
+
throw err;
|
|
44
|
+
})
|
|
45
|
+
.finally(() => {
|
|
46
|
+
obj.isClosed = true;
|
|
47
|
+
logger.verbose("is closed");
|
|
48
|
+
state.link = undefined;
|
|
49
|
+
state.authLoop = undefined;
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
abort: () => {
|
|
53
|
+
obj._onError?.(new AbortError(StandardAbortMessage));
|
|
54
|
+
logger.info(abortLogMessage);
|
|
55
|
+
return obj.close();
|
|
56
|
+
},
|
|
57
|
+
isOpen: () => {
|
|
58
|
+
const isOpen = !!state.link?.isOpen();
|
|
59
|
+
logger.verbose(`is open? -> ${isOpen}`);
|
|
60
|
+
return isOpen;
|
|
61
|
+
},
|
|
62
|
+
async connect({ abortSignal, timeoutInMs }) {
|
|
63
|
+
if (state.isConnecting || obj.isOpen()) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
state.isConnecting = true;
|
|
67
|
+
logger.verbose("is trying to connect");
|
|
68
|
+
try {
|
|
69
|
+
await ctx.readyToOpenLink({ abortSignal });
|
|
70
|
+
state.authLoop = await withAuth(() => setupLink(consumerId, ctx, name, address, obj, state, queue, eventPosition, logger, options, abortSignal), ctx, audience, timeoutInMs, logger, {
|
|
71
|
+
abortSignal,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
state.isConnecting = false;
|
|
76
|
+
const error = translate(err);
|
|
77
|
+
logger.error(`an error occurred while creating the receiver: ${error?.name}: ${error?.message}`);
|
|
78
|
+
logErrorStackTrace(err);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
receiveBatch: (maxMessageCount, maxWaitTimeInSeconds = 60, abortSignal) => {
|
|
83
|
+
const prefetchCount = options.prefetchCount ?? maxMessageCount * 3;
|
|
84
|
+
const cleanupBeforeAbort = () => {
|
|
85
|
+
logger.info(abortLogMessage);
|
|
86
|
+
return obj.close();
|
|
87
|
+
};
|
|
88
|
+
const retrieveEvents = () => {
|
|
89
|
+
const eventsToRetrieveCount = Math.max(maxMessageCount - queue.length, 0);
|
|
90
|
+
logger.verbose(`already has ${queue.length} events and wants to receive ${eventsToRetrieveCount} more events`);
|
|
91
|
+
if (abortSignal?.aborted) {
|
|
92
|
+
cleanupBeforeAbort();
|
|
93
|
+
return Promise.reject(new AbortError(StandardAbortMessage));
|
|
94
|
+
}
|
|
95
|
+
return obj.isClosed || ctx.wasConnectionCloseCalled || eventsToRetrieveCount === 0
|
|
96
|
+
? Promise.resolve(queue.splice(0, maxMessageCount))
|
|
97
|
+
: new Promise((resolve, reject) => {
|
|
98
|
+
obj._onError = reject;
|
|
99
|
+
obj // eslint-disable-line promise/catch-or-return
|
|
100
|
+
.connect({
|
|
101
|
+
abortSignal,
|
|
102
|
+
timeoutInMs: getRetryAttemptTimeoutInMs(options.retryOptions),
|
|
103
|
+
})
|
|
104
|
+
.then(() => {
|
|
105
|
+
addCredits(state.link, Math.max(prefetchCount, maxMessageCount) - queue.length);
|
|
106
|
+
logger.verbose(`setting the max wait time to ${maxWaitTimeInSeconds} seconds`);
|
|
107
|
+
return waitForEvents(maxMessageCount, maxWaitTimeInSeconds * 1000, qReadIntervalInMs, queue, {
|
|
108
|
+
abortSignal,
|
|
109
|
+
cleanupBeforeAbort,
|
|
110
|
+
receivedAfterWait: () => logger.info(`${Math.min(maxMessageCount, queue.length)} messages received within ${maxWaitTimeInSeconds} seconds`),
|
|
111
|
+
receivedAlready: () => logger.info(`${maxMessageCount} messages already received`),
|
|
112
|
+
receivedNone: () => logger.info(`no messages received when max wait time in seconds ${maxWaitTimeInSeconds} is over`),
|
|
113
|
+
});
|
|
114
|
+
})
|
|
115
|
+
.catch(reject)
|
|
116
|
+
.then(resolve);
|
|
117
|
+
})
|
|
118
|
+
.then(() => queue.splice(0, maxMessageCount))
|
|
119
|
+
.finally(() => clearHandlers(obj));
|
|
120
|
+
};
|
|
121
|
+
return retry(Object.defineProperties({
|
|
122
|
+
operation: retrieveEvents,
|
|
123
|
+
operationType: RetryOperationType.receiveMessage,
|
|
124
|
+
abortSignal: abortSignal,
|
|
125
|
+
retryOptions: options.retryOptions ?? {},
|
|
126
|
+
}, {
|
|
127
|
+
connectionId: {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
get: () => ctx.connectionId,
|
|
130
|
+
},
|
|
131
|
+
connectionHost: {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
get: () => ctx.config.host,
|
|
134
|
+
},
|
|
135
|
+
}));
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
return obj;
|
|
139
|
+
}
|
|
140
|
+
function delay(waitTimeInMs, options) {
|
|
141
|
+
let token;
|
|
142
|
+
return createAbortablePromise((resolve) => {
|
|
143
|
+
token = setTimeout(resolve, waitTimeInMs);
|
|
144
|
+
}, options).finally(() => clearTimeout(token));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
export function checkOnInterval(waitTimeInMs, check, options) {
|
|
150
|
+
let token;
|
|
151
|
+
return createAbortablePromise((resolve) => {
|
|
152
|
+
token = setInterval(() => {
|
|
153
|
+
if (check()) {
|
|
154
|
+
resolve();
|
|
155
|
+
}
|
|
156
|
+
}, waitTimeInMs);
|
|
157
|
+
}, options).finally(() => clearInterval(token));
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Returns a promise that will resolve when it is time to read from the queue
|
|
161
|
+
* @param maxEventCount - The maximum number of events to receive.
|
|
162
|
+
* @param maxWaitTimeInMs - The maximum time to wait in ms for the queue to contain any events.
|
|
163
|
+
* @param readIntervalWaitTimeInMs - The time interval to wait in ms before checking the queue.
|
|
164
|
+
* @param queue - The queue to read from.
|
|
165
|
+
* @param options - The options bag.
|
|
166
|
+
* @returns a promise that will resolve when it is time to read from the queue
|
|
167
|
+
* @internal
|
|
168
|
+
*/
|
|
169
|
+
export function waitForEvents(maxEventCount, maxWaitTimeInMs, readIntervalWaitTimeInMs, queue, options = {}) {
|
|
170
|
+
const { abortSignal: clientAbortSignal, cleanupBeforeAbort, receivedNone, receivedAfterWait, receivedAlready, } = options;
|
|
171
|
+
if (queue.length >= maxEventCount) {
|
|
172
|
+
return Promise.resolve().then(receivedAlready);
|
|
173
|
+
}
|
|
174
|
+
const aborter = new AbortController();
|
|
175
|
+
const abortListener = () => {
|
|
176
|
+
aborter.abort();
|
|
177
|
+
};
|
|
178
|
+
clientAbortSignal?.addEventListener("abort", abortListener);
|
|
179
|
+
let cleanupBeforeAbortCalled = false;
|
|
180
|
+
const updatedOptions = {
|
|
181
|
+
abortSignal: aborter.signal,
|
|
182
|
+
abortErrorMsg: StandardAbortMessage,
|
|
183
|
+
cleanupBeforeAbort: () => {
|
|
184
|
+
if (clientAbortSignal?.aborted && !cleanupBeforeAbortCalled) {
|
|
185
|
+
cleanupBeforeAbort?.();
|
|
186
|
+
cleanupBeforeAbortCalled = true;
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
return Promise.race([
|
|
191
|
+
checkOnInterval(readIntervalWaitTimeInMs, () => queue.length > 0, updatedOptions)
|
|
192
|
+
.then(() => delay(readIntervalWaitTimeInMs, updatedOptions))
|
|
193
|
+
.then(receivedAfterWait),
|
|
194
|
+
delay(maxWaitTimeInMs, updatedOptions).then(receivedNone),
|
|
195
|
+
]).finally(() => {
|
|
196
|
+
aborter.abort();
|
|
197
|
+
clientAbortSignal?.removeEventListener("abort", abortListener);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function convertAMQPMesage(data) {
|
|
201
|
+
const rawMessage = data.getRawAmqpMessage();
|
|
202
|
+
const receivedEventData = {
|
|
203
|
+
body: data.body,
|
|
204
|
+
properties: data.properties,
|
|
205
|
+
offset: data.offset,
|
|
206
|
+
sequenceNumber: data.sequenceNumber,
|
|
207
|
+
enqueuedTimeUtc: data.enqueuedTimeUtc,
|
|
208
|
+
partitionKey: data.partitionKey,
|
|
209
|
+
systemProperties: data.systemProperties,
|
|
210
|
+
getRawAmqpMessage() {
|
|
211
|
+
return rawMessage;
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
if (data.correlationId != null) {
|
|
215
|
+
receivedEventData.correlationId = data.correlationId;
|
|
216
|
+
}
|
|
217
|
+
if (data.contentType != null) {
|
|
218
|
+
receivedEventData.contentType = data.contentType;
|
|
219
|
+
}
|
|
220
|
+
if (data.messageId != null) {
|
|
221
|
+
receivedEventData.messageId = data.messageId;
|
|
222
|
+
}
|
|
223
|
+
return receivedEventData;
|
|
224
|
+
}
|
|
225
|
+
function setEventProps(eventProps, data) {
|
|
226
|
+
eventProps.sequenceNumber = data.lastSequenceNumber;
|
|
227
|
+
eventProps.enqueuedOn = data.lastEnqueuedTime;
|
|
228
|
+
eventProps.offset = data.lastEnqueuedOffset;
|
|
229
|
+
eventProps.retrievedOn = data.retrievalTime;
|
|
230
|
+
}
|
|
231
|
+
function clearHandlers(obj) {
|
|
232
|
+
obj._onError = undefined;
|
|
233
|
+
}
|
|
234
|
+
function onMessage(context, obj, queue, options) {
|
|
235
|
+
if (!context.message) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const data = fromRheaMessage(context.message, !!options.skipParsingBodyAsJson);
|
|
239
|
+
const receivedEventData = convertAMQPMesage(data);
|
|
240
|
+
obj.checkpoint = receivedEventData.sequenceNumber;
|
|
241
|
+
if (options.trackLastEnqueuedEventProperties) {
|
|
242
|
+
setEventProps(obj.lastEnqueuedEventProperties, data);
|
|
243
|
+
}
|
|
244
|
+
queue.push(receivedEventData);
|
|
245
|
+
}
|
|
246
|
+
function onError(context, obj, receiver, logger) {
|
|
247
|
+
const rheaReceiver = receiver || context.receiver;
|
|
248
|
+
const amqpError = rheaReceiver?.error;
|
|
249
|
+
logger.verbose(`'receiver_error' event occurred: ${logObj(amqpError)}`);
|
|
250
|
+
if (obj._onError && amqpError) {
|
|
251
|
+
const error = translate(amqpError);
|
|
252
|
+
logErrorStackTrace(error);
|
|
253
|
+
obj._onError(error);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function onSessionError(context, obj, logger) {
|
|
257
|
+
const sessionError = context.session?.error;
|
|
258
|
+
logger.verbose(`'session_error' event occurred: ${logObj(sessionError)}`);
|
|
259
|
+
if (obj._onError && sessionError) {
|
|
260
|
+
const error = translate(sessionError);
|
|
261
|
+
logErrorStackTrace(error);
|
|
262
|
+
obj._onError(error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function onClose(context, state, logger) {
|
|
266
|
+
const rheaReceiver = state.link || context.receiver;
|
|
267
|
+
logger.verbose(`'receiver_close' event occurred. Value for isItselfClosed on the receiver is: '${rheaReceiver
|
|
268
|
+
?.isItselfClosed()
|
|
269
|
+
.toString()}' Value for isConnecting on the session is: '${state.isConnecting}'`);
|
|
270
|
+
if (rheaReceiver && !state.isConnecting) {
|
|
271
|
+
rheaReceiver.close().catch((err) => {
|
|
272
|
+
logger.verbose(`error when closing after 'receiver_close' event: ${logObj(err)}`);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function onSessionClose(context, state, logger) {
|
|
277
|
+
const rheaReceiver = state.link || context.receiver;
|
|
278
|
+
logger.verbose(`'session_close' event occurred. Value for isSessionItselfClosed on the session is: '${rheaReceiver
|
|
279
|
+
?.isSessionItselfClosed()
|
|
280
|
+
.toString()}' Value for isConnecting on the session is: '${state.isConnecting}'`);
|
|
281
|
+
if (rheaReceiver && !state.isConnecting) {
|
|
282
|
+
rheaReceiver.close().catch((err) => {
|
|
283
|
+
logger.verbose(`error when closing after 'session_close' event: ${logObj(err)}`);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function createRheaOptions(consumerId, name, address, obj, state, queue, eventPosition, logger, options) {
|
|
288
|
+
const rheaOptions = {
|
|
289
|
+
name,
|
|
290
|
+
autoaccept: true,
|
|
291
|
+
target: consumerId,
|
|
292
|
+
source: {
|
|
293
|
+
address,
|
|
294
|
+
},
|
|
295
|
+
credit_window: 0,
|
|
296
|
+
properties: {
|
|
297
|
+
[receiverIdPropertyName]: consumerId,
|
|
298
|
+
},
|
|
299
|
+
onClose: (context) => onClose(context, state, logger),
|
|
300
|
+
onSessionClose: (context) => onSessionClose(context, state, logger),
|
|
301
|
+
onError: (context) => onError(context, obj, state.link, logger),
|
|
302
|
+
onMessage: (context) => onMessage(context, obj, queue, options),
|
|
303
|
+
onSessionError: (context) => onSessionError(context, obj, logger),
|
|
304
|
+
};
|
|
305
|
+
const ownerLevel = options.ownerLevel;
|
|
306
|
+
if (typeof ownerLevel === "number") {
|
|
307
|
+
rheaOptions.properties[Constants.attachEpoch] = types.wrap_long(ownerLevel);
|
|
308
|
+
}
|
|
309
|
+
rheaOptions.desired_capabilities = [geoReplication];
|
|
310
|
+
if (options.trackLastEnqueuedEventProperties) {
|
|
311
|
+
rheaOptions.desired_capabilities.push(Constants.enableReceiverRuntimeMetricName);
|
|
312
|
+
}
|
|
313
|
+
const filterClause = getEventPositionFilter(obj.checkpoint > -1 ? { sequenceNumber: obj.checkpoint } : eventPosition);
|
|
314
|
+
rheaOptions.source.filter = {
|
|
315
|
+
"apache.org:selector-filter:string": types.wrap_described(filterClause, 0x468c00000004),
|
|
316
|
+
};
|
|
317
|
+
return rheaOptions;
|
|
318
|
+
}
|
|
319
|
+
async function setupLink(consumerId, ctx, name, address, obj, state, queue, eventPosition, logger, options, abortSignal) {
|
|
320
|
+
const rheaOptions = createRheaOptions(consumerId, name, address, obj, state, queue, eventPosition, logger, options);
|
|
321
|
+
logger.verbose(`trying to be created with options ${logObj(rheaOptions)}`);
|
|
322
|
+
state.link = await ctx.connection.createReceiver({
|
|
323
|
+
...rheaOptions,
|
|
324
|
+
abortSignal,
|
|
325
|
+
});
|
|
326
|
+
state.isConnecting = false;
|
|
327
|
+
logger.verbose("is created successfully");
|
|
328
|
+
ctx.receivers[name] = obj;
|
|
329
|
+
}
|
|
330
|
+
function addCredits(receiver, creditsToAdd) {
|
|
331
|
+
if (creditsToAdd > 0) {
|
|
332
|
+
receiver?.addCredit(creditsToAdd);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=partitionReceiver.js.map
|