@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,255 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
import { delay } from "@azure/core-amqp";
|
|
4
|
+
import { isDefined, isObjectWithProperties } from "@azure/core-util";
|
|
5
|
+
import { AwaitableQueue } from "./impl/awaitableQueue.js";
|
|
6
|
+
import { getPromiseParts } from "./util/getPromiseParts.js";
|
|
7
|
+
import { logger } from "./logger.js";
|
|
8
|
+
import { cancelablePromiseRace } from "@azure/core-util";
|
|
9
|
+
/**
|
|
10
|
+
* The `BatchingPartitionChannel` is responsible for accepting enqueued events
|
|
11
|
+
* and optimally batching and sending them to an Event Hub.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export class BatchingPartitionChannel {
|
|
15
|
+
_eventQueue = new AwaitableQueue();
|
|
16
|
+
_batchedEvents = [];
|
|
17
|
+
_bufferCount = 0;
|
|
18
|
+
_readyQueue = [];
|
|
19
|
+
_flushState = {
|
|
20
|
+
isFlushing: false,
|
|
21
|
+
};
|
|
22
|
+
_isRunning = false;
|
|
23
|
+
_lastBatchCreationTime = 0;
|
|
24
|
+
_loopAbortSignal;
|
|
25
|
+
_maxBufferSize;
|
|
26
|
+
_maxWaitTimeInMs;
|
|
27
|
+
_onSendEventsErrorHandler;
|
|
28
|
+
_onSendEventsSuccessHandler;
|
|
29
|
+
_partitionId;
|
|
30
|
+
_producer;
|
|
31
|
+
constructor({ loopAbortSignal, maxBufferSize, maxWaitTimeInMs, onSendEventsErrorHandler, onSendEventsSuccessHandler, partitionId, producer, }) {
|
|
32
|
+
this._loopAbortSignal = loopAbortSignal;
|
|
33
|
+
this._maxBufferSize = maxBufferSize;
|
|
34
|
+
this._maxWaitTimeInMs = maxWaitTimeInMs;
|
|
35
|
+
this._onSendEventsErrorHandler = onSendEventsErrorHandler;
|
|
36
|
+
this._onSendEventsSuccessHandler = onSendEventsSuccessHandler;
|
|
37
|
+
this._partitionId = partitionId;
|
|
38
|
+
this._producer = producer;
|
|
39
|
+
}
|
|
40
|
+
getCurrentBufferedCount() {
|
|
41
|
+
return this._bufferCount;
|
|
42
|
+
}
|
|
43
|
+
async enqueueEvent(event) {
|
|
44
|
+
await this._ready();
|
|
45
|
+
this._eventQueue.push(event);
|
|
46
|
+
this._bufferCount++;
|
|
47
|
+
if (!this._isRunning) {
|
|
48
|
+
this._isRunning = true;
|
|
49
|
+
// Fire-and-forget background loop with error handling
|
|
50
|
+
this._startPublishLoop().catch((e) => {
|
|
51
|
+
logger.error(`The following error occurred during batch creation or sending: ${JSON.stringify(e, undefined, " ")}`);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Sets the flush state so that no new events can be enqueued until
|
|
57
|
+
* all the currently buffered events are sent to the Event Hub.
|
|
58
|
+
*
|
|
59
|
+
* Returns a promise that resolves once flushing is complete.
|
|
60
|
+
*/
|
|
61
|
+
async flush(_options = {}) {
|
|
62
|
+
const state = this._flushState;
|
|
63
|
+
if (state.isFlushing) {
|
|
64
|
+
return state.currentPromise;
|
|
65
|
+
}
|
|
66
|
+
if (this.getCurrentBufferedCount() === 0) {
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
const { promise, resolve } = getPromiseParts();
|
|
70
|
+
this._flushState = { isFlushing: true, currentPromise: promise, resolve };
|
|
71
|
+
return promise;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns a promise that resolves once there is room for events to be added
|
|
75
|
+
* to the buffer.
|
|
76
|
+
*/
|
|
77
|
+
_ready() {
|
|
78
|
+
const currentBufferedCount = this.getCurrentBufferedCount();
|
|
79
|
+
// If the buffer isn't full and we don't have any pending `ready()` calls,
|
|
80
|
+
// then it's safe to return right away.
|
|
81
|
+
if (currentBufferedCount < this._maxBufferSize &&
|
|
82
|
+
!this._readyQueue.length &&
|
|
83
|
+
!this._flushState.isFlushing) {
|
|
84
|
+
return Promise.resolve();
|
|
85
|
+
}
|
|
86
|
+
const { promise: readyPromise, reject, resolve } = getPromiseParts();
|
|
87
|
+
this._readyQueue.push({ resolve, reject });
|
|
88
|
+
return readyPromise;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Starts the loop that creates batches and sends them to the Event Hub.
|
|
92
|
+
*
|
|
93
|
+
* The loop will run until the `_loopAbortSignal` is aborted.
|
|
94
|
+
*/
|
|
95
|
+
async _startPublishLoop() {
|
|
96
|
+
let batch;
|
|
97
|
+
// `eventToAddToBatch` is used to keep track of an event that has been removed
|
|
98
|
+
// from the queue, but has not yet been added to a batch.
|
|
99
|
+
// This prevents losing an event if a `sendBatch` or `createBatch` call fails
|
|
100
|
+
// before the event is added to a batch.
|
|
101
|
+
let eventToAddToBatch;
|
|
102
|
+
while (!this._loopAbortSignal.aborted) {
|
|
103
|
+
try {
|
|
104
|
+
if (!isDefined(batch)) {
|
|
105
|
+
batch = await this._createBatch();
|
|
106
|
+
}
|
|
107
|
+
const timeSinceLastBatchCreation = Date.now() - this._lastBatchCreationTime;
|
|
108
|
+
const maximumTimeToWaitForEvent = batch.count
|
|
109
|
+
? Math.max(this._maxWaitTimeInMs - timeSinceLastBatchCreation, 0)
|
|
110
|
+
: this._maxWaitTimeInMs;
|
|
111
|
+
const event = eventToAddToBatch ??
|
|
112
|
+
(await cancelablePromiseRace([
|
|
113
|
+
(abortOptions) => this._eventQueue.shift(abortOptions),
|
|
114
|
+
(abortOptions) => delay(maximumTimeToWaitForEvent, abortOptions.abortSignal, abortOptions.abortErrorMsg),
|
|
115
|
+
], { abortSignal: this._loopAbortSignal }));
|
|
116
|
+
if (!event) {
|
|
117
|
+
// We didn't receive an event within the allotted time.
|
|
118
|
+
// Send the existing batch if it has events in it.
|
|
119
|
+
if (batch.count) {
|
|
120
|
+
await this._producer.sendBatch(batch);
|
|
121
|
+
this._reportSuccess();
|
|
122
|
+
batch = await this._createBatch();
|
|
123
|
+
}
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
else if (!eventToAddToBatch) {
|
|
127
|
+
eventToAddToBatch = event;
|
|
128
|
+
}
|
|
129
|
+
const didAdd = batch.tryAdd(event);
|
|
130
|
+
if (didAdd) {
|
|
131
|
+
// This event will definitely make it to one of the user-provided handlers
|
|
132
|
+
// since it was added to a batch.
|
|
133
|
+
// Store it so we can return it in a handler later.
|
|
134
|
+
this._batchedEvents.push(event);
|
|
135
|
+
// Clear reference to existing event since it has been added to the batch.
|
|
136
|
+
eventToAddToBatch = undefined;
|
|
137
|
+
}
|
|
138
|
+
if (didAdd && batch.count >= this._maxBufferSize) {
|
|
139
|
+
// Whenever batch.count exceeds the max count of buffered events, send the batch.
|
|
140
|
+
await this._producer.sendBatch(batch);
|
|
141
|
+
this._reportSuccess();
|
|
142
|
+
batch = await this._createBatch();
|
|
143
|
+
}
|
|
144
|
+
else if (!didAdd && batch.count) {
|
|
145
|
+
// If the event wasn't able to be added and the current batch isn't empty,
|
|
146
|
+
// attempt to send the current batch and add the event to a new batch.
|
|
147
|
+
await this._producer.sendBatch(batch);
|
|
148
|
+
this._reportSuccess();
|
|
149
|
+
batch = await this._createBatch();
|
|
150
|
+
}
|
|
151
|
+
if (!didAdd && !batch.tryAdd(event)) {
|
|
152
|
+
// TODO: Report MaxMesageSizeExceeded error. Mimic service's error.
|
|
153
|
+
this._reportFailure(new Error("Placeholder for max message size exceeded"), event);
|
|
154
|
+
}
|
|
155
|
+
else if (!didAdd) {
|
|
156
|
+
// Handles the case where the event _was_ successfull added to the new batch.
|
|
157
|
+
this._batchedEvents.push(event);
|
|
158
|
+
}
|
|
159
|
+
// Clear reference to existing event since it has been added to the batch.
|
|
160
|
+
eventToAddToBatch = undefined;
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
if (!isObjectWithProperties(err, ["name"]) || err.name !== "AbortError") {
|
|
164
|
+
this._reportFailure(err);
|
|
165
|
+
batch = undefined;
|
|
166
|
+
this._batchedEvents = [];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Helper method that returns an `EventDataBatch`.
|
|
173
|
+
* This also has the side effects of
|
|
174
|
+
* - keeping track of batch creation time: needed for maxWaitTime calculations.
|
|
175
|
+
* - clearing reference to batched events.
|
|
176
|
+
* - incrementing the readiness: creating a new batch indicates the buffer
|
|
177
|
+
* should have room, so we can resolve some pending `ready()` calls.
|
|
178
|
+
*/
|
|
179
|
+
async _createBatch() {
|
|
180
|
+
this._lastBatchCreationTime = Date.now();
|
|
181
|
+
this._batchedEvents = [];
|
|
182
|
+
const batch = await this._producer.createBatch({
|
|
183
|
+
partitionId: this._partitionId,
|
|
184
|
+
});
|
|
185
|
+
this._incrementReadiness();
|
|
186
|
+
return batch;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* This method will resolve as many pending `ready()` calls as it can
|
|
190
|
+
* based on how much space remains in the buffer.
|
|
191
|
+
*
|
|
192
|
+
* If the channel is currently flushing, this is a no-op. This prevents
|
|
193
|
+
* `enqueueEvent` calls from adding the event to the buffer until flushing
|
|
194
|
+
* completes.
|
|
195
|
+
*/
|
|
196
|
+
_incrementReadiness() {
|
|
197
|
+
if (this._flushState.isFlushing) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const currentBufferedCount = this.getCurrentBufferedCount();
|
|
201
|
+
const num = Math.min(this._maxBufferSize - currentBufferedCount, this._readyQueue.length);
|
|
202
|
+
for (let i = 0; i < num; i++) {
|
|
203
|
+
this._readyQueue.shift()?.resolve();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Calls the user-provided `onSendEventsSuccessHandler` with the events
|
|
208
|
+
* that were successfully sent.
|
|
209
|
+
*/
|
|
210
|
+
_reportSuccess() {
|
|
211
|
+
this._bufferCount = this._bufferCount - this._batchedEvents.length;
|
|
212
|
+
this._updateFlushState();
|
|
213
|
+
try {
|
|
214
|
+
this._onSendEventsSuccessHandler?.({
|
|
215
|
+
events: this._batchedEvents,
|
|
216
|
+
partitionId: this._partitionId,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
logger.error(`The following error occurred in the onSendEventsSuccessHandler: ${JSON.stringify(e, undefined, " ")}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Calls the user-provided `onSendEventsErrorHandler` with an error and the events
|
|
225
|
+
* that were not successfully sent.
|
|
226
|
+
*/
|
|
227
|
+
_reportFailure(err, event) {
|
|
228
|
+
this._bufferCount = this._bufferCount - (event ? 1 : this._batchedEvents.length);
|
|
229
|
+
this._updateFlushState();
|
|
230
|
+
try {
|
|
231
|
+
this._onSendEventsErrorHandler({
|
|
232
|
+
error: err,
|
|
233
|
+
events: event ? [event] : this._batchedEvents,
|
|
234
|
+
partitionId: this._partitionId,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
logger.error(`The following error occurred in the onSendEventsErrorHandler: ${JSON.stringify(e, undefined, " ")}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Updates the channel's flush state once the size of the
|
|
243
|
+
* event buffer has decreased to 0.
|
|
244
|
+
*/
|
|
245
|
+
_updateFlushState() {
|
|
246
|
+
const state = this._flushState;
|
|
247
|
+
if (!state.isFlushing || this.getCurrentBufferedCount() !== 0) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
state.resolve();
|
|
251
|
+
this._flushState = { isFlushing: false };
|
|
252
|
+
this._incrementReadiness();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=batchingPartitionChannel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchingPartitionChannel.js","sourceRoot":"","sources":["../../src/batchingPartitionChannel.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AmqpAnnotatedMessage } from \"@azure/core-amqp\";\nimport { delay } from \"@azure/core-amqp\";\nimport type {\n EventData,\n EventDataBatch,\n EventHubBufferedProducerClientOptions,\n EventHubProducerClient,\n OperationOptions,\n} from \"./index.js\";\nimport type { AbortOptions } from \"@azure/core-util\";\nimport { isDefined, isObjectWithProperties } from \"@azure/core-util\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AwaitableQueue } from \"./impl/awaitableQueue.js\";\nimport { getPromiseParts } from \"./util/getPromiseParts.js\";\nimport { logger } from \"./logger.js\";\nimport { cancelablePromiseRace } from \"@azure/core-util\";\n\nexport interface BatchingPartitionChannelProps {\n loopAbortSignal: AbortSignalLike;\n maxBufferSize: number;\n maxWaitTimeInMs: number;\n partitionId: string;\n producer: EventHubProducerClient;\n /**\n * The handler to call once a batch has successfully published.\n */\n onSendEventsSuccessHandler?: EventHubBufferedProducerClientOptions[\"onSendEventsSuccessHandler\"];\n /**\n * The handler to call when a batch fails to publish.\n */\n onSendEventsErrorHandler: EventHubBufferedProducerClientOptions[\"onSendEventsErrorHandler\"];\n}\n\n/**\n * The `BatchingPartitionChannel` is responsible for accepting enqueued events\n * and optimally batching and sending them to an Event Hub.\n * @internal\n */\nexport class BatchingPartitionChannel {\n private _eventQueue = new AwaitableQueue<EventData | AmqpAnnotatedMessage>();\n private _batchedEvents: Array<EventData | AmqpAnnotatedMessage> = [];\n private _bufferCount: number = 0;\n private _readyQueue: Array<{\n resolve: (value: void) => void;\n reject: (reason?: any) => void;\n }> = [];\n private _flushState:\n | { isFlushing: false }\n | { isFlushing: true; currentPromise: Promise<void>; resolve: () => void } = {\n isFlushing: false,\n };\n private _isRunning: boolean = false;\n private _lastBatchCreationTime: number = 0;\n private _loopAbortSignal: AbortSignalLike;\n private _maxBufferSize: number;\n private _maxWaitTimeInMs: number;\n private _onSendEventsErrorHandler: EventHubBufferedProducerClientOptions[\"onSendEventsErrorHandler\"];\n private _onSendEventsSuccessHandler?: EventHubBufferedProducerClientOptions[\"onSendEventsSuccessHandler\"];\n\n private _partitionId: string;\n private _producer: EventHubProducerClient;\n\n constructor({\n loopAbortSignal,\n maxBufferSize,\n maxWaitTimeInMs,\n onSendEventsErrorHandler,\n onSendEventsSuccessHandler,\n partitionId,\n producer,\n }: BatchingPartitionChannelProps) {\n this._loopAbortSignal = loopAbortSignal;\n this._maxBufferSize = maxBufferSize;\n this._maxWaitTimeInMs = maxWaitTimeInMs;\n this._onSendEventsErrorHandler = onSendEventsErrorHandler;\n this._onSendEventsSuccessHandler = onSendEventsSuccessHandler;\n this._partitionId = partitionId;\n this._producer = producer;\n }\n\n getCurrentBufferedCount(): number {\n return this._bufferCount;\n }\n\n async enqueueEvent(event: EventData | AmqpAnnotatedMessage): Promise<void> {\n await this._ready();\n this._eventQueue.push(event);\n this._bufferCount++;\n\n if (!this._isRunning) {\n this._isRunning = true;\n // Fire-and-forget background loop with error handling\n this._startPublishLoop().catch((e) => {\n logger.error(\n `The following error occurred during batch creation or sending: ${JSON.stringify(\n e,\n undefined,\n \" \",\n )}`,\n );\n });\n }\n }\n\n /**\n * Sets the flush state so that no new events can be enqueued until\n * all the currently buffered events are sent to the Event Hub.\n *\n * Returns a promise that resolves once flushing is complete.\n */\n async flush(_options: OperationOptions = {}): Promise<void> {\n const state = this._flushState;\n if (state.isFlushing) {\n return state.currentPromise;\n }\n\n if (this.getCurrentBufferedCount() === 0) {\n return Promise.resolve();\n }\n\n const { promise, resolve } = getPromiseParts<void>();\n this._flushState = { isFlushing: true, currentPromise: promise, resolve };\n\n return promise;\n }\n\n /**\n * Returns a promise that resolves once there is room for events to be added\n * to the buffer.\n */\n private _ready(): Promise<void> {\n const currentBufferedCount = this.getCurrentBufferedCount();\n\n // If the buffer isn't full and we don't have any pending `ready()` calls,\n // then it's safe to return right away.\n if (\n currentBufferedCount < this._maxBufferSize &&\n !this._readyQueue.length &&\n !this._flushState.isFlushing\n ) {\n return Promise.resolve();\n }\n\n const { promise: readyPromise, reject, resolve } = getPromiseParts<void>();\n this._readyQueue.push({ resolve, reject });\n\n return readyPromise;\n }\n\n /**\n * Starts the loop that creates batches and sends them to the Event Hub.\n *\n * The loop will run until the `_loopAbortSignal` is aborted.\n */\n private async _startPublishLoop() {\n let batch: EventDataBatch | undefined;\n // `eventToAddToBatch` is used to keep track of an event that has been removed\n // from the queue, but has not yet been added to a batch.\n // This prevents losing an event if a `sendBatch` or `createBatch` call fails\n // before the event is added to a batch.\n let eventToAddToBatch: EventData | AmqpAnnotatedMessage | undefined;\n while (!this._loopAbortSignal.aborted) {\n try {\n if (!isDefined(batch)) {\n batch = await this._createBatch();\n }\n const timeSinceLastBatchCreation = Date.now() - this._lastBatchCreationTime;\n const maximumTimeToWaitForEvent = batch.count\n ? Math.max(this._maxWaitTimeInMs - timeSinceLastBatchCreation, 0)\n : this._maxWaitTimeInMs;\n\n const event =\n eventToAddToBatch ??\n (await cancelablePromiseRace<[EventData | AmqpAnnotatedMessage, void]>(\n [\n (abortOptions: AbortOptions) => this._eventQueue.shift(abortOptions),\n (abortOptions: AbortOptions) =>\n delay<void>(\n maximumTimeToWaitForEvent,\n abortOptions.abortSignal,\n abortOptions.abortErrorMsg,\n ),\n ],\n { abortSignal: this._loopAbortSignal },\n ));\n\n if (!event) {\n // We didn't receive an event within the allotted time.\n // Send the existing batch if it has events in it.\n if (batch.count) {\n await this._producer.sendBatch(batch);\n this._reportSuccess();\n batch = await this._createBatch();\n }\n continue;\n } else if (!eventToAddToBatch) {\n eventToAddToBatch = event;\n }\n\n const didAdd = batch.tryAdd(event);\n if (didAdd) {\n // This event will definitely make it to one of the user-provided handlers\n // since it was added to a batch.\n // Store it so we can return it in a handler later.\n this._batchedEvents.push(event);\n // Clear reference to existing event since it has been added to the batch.\n eventToAddToBatch = undefined;\n }\n\n if (didAdd && batch.count >= this._maxBufferSize) {\n // Whenever batch.count exceeds the max count of buffered events, send the batch.\n await this._producer.sendBatch(batch);\n this._reportSuccess();\n batch = await this._createBatch();\n } else if (!didAdd && batch.count) {\n // If the event wasn't able to be added and the current batch isn't empty,\n // attempt to send the current batch and add the event to a new batch.\n await this._producer.sendBatch(batch);\n this._reportSuccess();\n batch = await this._createBatch();\n }\n\n if (!didAdd && !batch.tryAdd(event)) {\n // TODO: Report MaxMesageSizeExceeded error. Mimic service's error.\n this._reportFailure(new Error(\"Placeholder for max message size exceeded\"), event);\n } else if (!didAdd) {\n // Handles the case where the event _was_ successfull added to the new batch.\n this._batchedEvents.push(event);\n }\n // Clear reference to existing event since it has been added to the batch.\n eventToAddToBatch = undefined;\n } catch (err: any) {\n if (!isObjectWithProperties(err, [\"name\"]) || err.name !== \"AbortError\") {\n this._reportFailure(err);\n batch = undefined;\n this._batchedEvents = [];\n }\n }\n }\n }\n\n /**\n * Helper method that returns an `EventDataBatch`.\n * This also has the side effects of\n * - keeping track of batch creation time: needed for maxWaitTime calculations.\n * - clearing reference to batched events.\n * - incrementing the readiness: creating a new batch indicates the buffer\n * should have room, so we can resolve some pending `ready()` calls.\n */\n private async _createBatch(): Promise<EventDataBatch> {\n this._lastBatchCreationTime = Date.now();\n this._batchedEvents = [];\n const batch = await this._producer.createBatch({\n partitionId: this._partitionId,\n });\n this._incrementReadiness();\n return batch;\n }\n\n /**\n * This method will resolve as many pending `ready()` calls as it can\n * based on how much space remains in the buffer.\n *\n * If the channel is currently flushing, this is a no-op. This prevents\n * `enqueueEvent` calls from adding the event to the buffer until flushing\n * completes.\n */\n private _incrementReadiness() {\n if (this._flushState.isFlushing) {\n return;\n }\n const currentBufferedCount = this.getCurrentBufferedCount();\n const num = Math.min(this._maxBufferSize - currentBufferedCount, this._readyQueue.length);\n for (let i = 0; i < num; i++) {\n this._readyQueue.shift()?.resolve();\n }\n }\n\n /**\n * Calls the user-provided `onSendEventsSuccessHandler` with the events\n * that were successfully sent.\n */\n private _reportSuccess() {\n this._bufferCount = this._bufferCount - this._batchedEvents.length;\n this._updateFlushState();\n try {\n this._onSendEventsSuccessHandler?.({\n events: this._batchedEvents,\n partitionId: this._partitionId,\n });\n } catch (e: unknown) {\n logger.error(\n `The following error occurred in the onSendEventsSuccessHandler: ${JSON.stringify(\n e,\n undefined,\n \" \",\n )}`,\n );\n }\n }\n\n /**\n * Calls the user-provided `onSendEventsErrorHandler` with an error and the events\n * that were not successfully sent.\n */\n private _reportFailure(err: any, event?: EventData | AmqpAnnotatedMessage) {\n this._bufferCount = this._bufferCount - (event ? 1 : this._batchedEvents.length);\n this._updateFlushState();\n try {\n this._onSendEventsErrorHandler({\n error: err,\n events: event ? [event] : this._batchedEvents,\n partitionId: this._partitionId,\n });\n } catch (e: unknown) {\n logger.error(\n `The following error occurred in the onSendEventsErrorHandler: ${JSON.stringify(\n e,\n undefined,\n \" \",\n )}`,\n );\n }\n }\n\n /**\n * Updates the channel's flush state once the size of the\n * event buffer has decreased to 0.\n */\n private _updateFlushState() {\n const state = this._flushState;\n if (!state.isFlushing || this.getCurrentBufferedCount() !== 0) {\n return;\n }\n\n state.resolve();\n\n this._flushState = { isFlushing: false };\n this._incrementReadiness();\n }\n}\n"]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Dictionary } from "rhea-promise";
|
|
2
|
+
import type { SasTokenProvider } from "@azure/core-amqp";
|
|
3
|
+
import { ConnectionContextBase } from "@azure/core-amqp";
|
|
4
|
+
import { ManagementClient } from "./managementClient.js";
|
|
5
|
+
import type { NamedKeyCredential, SASCredential, TokenCredential } from "@azure/core-auth";
|
|
6
|
+
import type { EventHubClientOptions } from "./models/public.js";
|
|
7
|
+
import { EventHubConnectionConfig } from "./eventhubConnectionConfig.js";
|
|
8
|
+
import type { PartitionReceiver } from "./partitionReceiver.js";
|
|
9
|
+
import type { EventHubSender } from "./eventHubSender.js";
|
|
10
|
+
import type { AbortSignalLike } from "@azure/abort-controller";
|
|
11
|
+
/**
|
|
12
|
+
* @internal
|
|
13
|
+
* Provides contextual information like the underlying amqp connection, cbs session, management session,
|
|
14
|
+
* tokenProvider, senders, receivers, etc. about the EventHub client.
|
|
15
|
+
*/
|
|
16
|
+
export interface ConnectionContext extends ConnectionContextBase {
|
|
17
|
+
/**
|
|
18
|
+
* The EventHub connection config that is created after
|
|
19
|
+
* parsing the connection string.
|
|
20
|
+
*/
|
|
21
|
+
readonly config: EventHubConnectionConfig;
|
|
22
|
+
/**
|
|
23
|
+
* The credential to be used for Authentication.
|
|
24
|
+
* Default value: SasTokenProvider.
|
|
25
|
+
*/
|
|
26
|
+
tokenCredential: SasTokenProvider | TokenCredential;
|
|
27
|
+
/**
|
|
28
|
+
* Indicates whether the close() method was
|
|
29
|
+
* called on theconnection object.
|
|
30
|
+
*/
|
|
31
|
+
wasConnectionCloseCalled: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* A dictionary of the EventHub Receivers associated with this client.
|
|
34
|
+
*/
|
|
35
|
+
receivers: Dictionary<PartitionReceiver>;
|
|
36
|
+
/**
|
|
37
|
+
* A dictionary of the EventHub Senders associated with this client.
|
|
38
|
+
*/
|
|
39
|
+
senders: Dictionary<EventHubSender>;
|
|
40
|
+
/**
|
|
41
|
+
* A reference to the management session ($management endpoint) on
|
|
42
|
+
* the underlying amqp connection for the EventHub Client.
|
|
43
|
+
*/
|
|
44
|
+
managementSession?: ManagementClient;
|
|
45
|
+
/**
|
|
46
|
+
* Function returning a promise that resolves once the connectionContext is ready to open an AMQP link.
|
|
47
|
+
* ConnectionContext will be ready to open an AMQP link when:
|
|
48
|
+
* - The AMQP connection is already open on both sides.
|
|
49
|
+
* - The AMQP connection has been closed or disconnected. In this case, a new AMQP connection is expected
|
|
50
|
+
* to be created first.
|
|
51
|
+
* An AMQP link cannot be opened if the AMQP connection
|
|
52
|
+
* is in the process of closing or disconnecting.
|
|
53
|
+
*/
|
|
54
|
+
readyToOpenLink(options?: {
|
|
55
|
+
abortSignal?: AbortSignalLike;
|
|
56
|
+
}): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Closes all AMQP links, sessions and connection.
|
|
59
|
+
*/
|
|
60
|
+
close(): Promise<void>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Describes the members on the ConnectionContext that are only
|
|
64
|
+
* used by it internally.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export interface ConnectionContextInternalMembers extends ConnectionContext {
|
|
68
|
+
/**
|
|
69
|
+
* Indicates whether the connection is in the process of closing.
|
|
70
|
+
* When this returns `true`, a `disconnected` event will be received
|
|
71
|
+
* after the connection is closed.
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
74
|
+
isConnectionClosing(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Resolves once the context's connection emits a `disconnected` event.
|
|
77
|
+
*/
|
|
78
|
+
waitForDisconnectedEvent(options?: {
|
|
79
|
+
abortSignal?: AbortSignalLike;
|
|
80
|
+
}): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Resolves once the connection has finished being reset.
|
|
83
|
+
* Connections are reset as part of reacting to a `disconnected` event.
|
|
84
|
+
*/
|
|
85
|
+
waitForConnectionReset(): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
export interface ConnectionContextOptions extends EventHubClientOptions {
|
|
91
|
+
managementSessionAddress?: string;
|
|
92
|
+
managementSessionAudience?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export declare namespace ConnectionContext {
|
|
98
|
+
function getUserAgent(options: ConnectionContextOptions): string;
|
|
99
|
+
function create(config: EventHubConnectionConfig, tokenCredential: SasTokenProvider | TokenCredential, options?: ConnectionContextOptions): ConnectionContext;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Helper method to create a ConnectionContext from the input passed to either
|
|
103
|
+
* EventHubProducerClient or EventHubConsumerClient constructors
|
|
104
|
+
*
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export declare function createConnectionContext(hostOrConnectionString: string, eventHubNameOrOptions?: string | EventHubClientOptions, credentialOrOptions?: TokenCredential | NamedKeyCredential | SASCredential | EventHubClientOptions, options?: EventHubClientOptions): ConnectionContext;
|
|
108
|
+
//# sourceMappingURL=connectionContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionContext.d.ts","sourceRoot":"","sources":["../../src/connectionContext.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAc,UAAU,EAA6B,MAAM,cAAc,CAAC;AAEtF,OAAO,KAAK,EAAyC,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAEL,qBAAqB,EAGtB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAG3F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC9D;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C;;;OAGG;IACH,eAAe,EAAE,gBAAgB,GAAG,eAAe,CAAC;IACpD;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;OAEG;IACH,SAAS,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC;IACzC;;OAEG;IACH,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;IACrC;;;;;;;;OAQG;IACH,eAAe,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,gCAAiC,SAAQ,iBAAiB;IACzE;;;;;OAKG;IACH,mBAAmB,IAAI,OAAO,CAAC;IAC/B;;OAEG;IACH,wBAAwB,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,eAAe,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF;;;OAGG;IACH,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;IACrE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAsBD;;GAEG;AACH,yBAAiB,iBAAiB,CAAC;IASjC,SAAgB,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAStE;IAED,SAAgB,MAAM,CACpB,MAAM,EAAE,wBAAwB,EAChC,eAAe,EAAE,gBAAgB,GAAG,eAAe,EACnD,OAAO,CAAC,EAAE,wBAAwB,GACjC,iBAAiB,CAmTnB;CACF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,sBAAsB,EAAE,MAAM,EAC9B,qBAAqB,CAAC,EAAE,MAAM,GAAG,qBAAqB,EACtD,mBAAmB,CAAC,EAChB,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,qBAAqB,EACzB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,iBAAiB,CAyEnB"}
|