@azure/service-bus 7.10.0-beta.2 → 7.10.0-beta.3

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.
Files changed (254) hide show
  1. package/dist/browser/connectionContext.js +1 -2
  2. package/dist/browser/connectionContext.js.map +1 -1
  3. package/dist/browser/constructorHelpers.js +3 -4
  4. package/dist/browser/constructorHelpers.js.map +1 -1
  5. package/dist/browser/core/autoLockRenewer.js +9 -5
  6. package/dist/browser/core/autoLockRenewer.js.map +1 -1
  7. package/dist/browser/core/batchingReceiver.js +26 -18
  8. package/dist/browser/core/batchingReceiver.js.map +1 -1
  9. package/dist/browser/core/linkEntity.js +74 -13
  10. package/dist/browser/core/linkEntity.js.map +1 -1
  11. package/dist/browser/core/managementClient.js +48 -48
  12. package/dist/browser/core/managementClient.js.map +1 -1
  13. package/dist/browser/core/messageReceiver.js +41 -14
  14. package/dist/browser/core/messageReceiver.js.map +1 -1
  15. package/dist/browser/core/messageSender.js +33 -10
  16. package/dist/browser/core/messageSender.js.map +1 -1
  17. package/dist/browser/core/receiverHelper.js +3 -2
  18. package/dist/browser/core/receiverHelper.js.map +1 -1
  19. package/dist/browser/core/shared.js +11 -4
  20. package/dist/browser/core/shared.js.map +1 -1
  21. package/dist/browser/core/streamingReceiver.js +74 -43
  22. package/dist/browser/core/streamingReceiver.js.map +1 -1
  23. package/dist/browser/diagnostics/instrumentServiceBusMessage.js +16 -8
  24. package/dist/browser/diagnostics/instrumentServiceBusMessage.js.map +1 -1
  25. package/dist/browser/receivers/receiver.js +68 -23
  26. package/dist/browser/receivers/receiver.js.map +1 -1
  27. package/dist/browser/receivers/receiverCommon.js +36 -21
  28. package/dist/browser/receivers/receiverCommon.js.map +1 -1
  29. package/dist/browser/receivers/sessionReceiver.js +69 -29
  30. package/dist/browser/receivers/sessionReceiver.js.map +1 -1
  31. package/dist/browser/sender.js +33 -11
  32. package/dist/browser/sender.js.map +1 -1
  33. package/dist/browser/serializers/queueResourceSerializer.js +9 -1
  34. package/dist/browser/serializers/queueResourceSerializer.js.map +1 -1
  35. package/dist/browser/serializers/ruleResourceSerializer.js +1 -2
  36. package/dist/browser/serializers/ruleResourceSerializer.js.map +1 -1
  37. package/dist/browser/serviceBusAtomManagementClient.js +181 -228
  38. package/dist/browser/serviceBusAtomManagementClient.js.map +1 -1
  39. package/dist/browser/serviceBusClient.js +31 -22
  40. package/dist/browser/serviceBusClient.js.map +1 -1
  41. package/dist/browser/serviceBusError.js +21 -1
  42. package/dist/browser/serviceBusError.js.map +1 -1
  43. package/dist/browser/serviceBusMessage.js +208 -13
  44. package/dist/browser/serviceBusMessage.js.map +1 -1
  45. package/dist/browser/serviceBusMessageBatch.js +32 -8
  46. package/dist/browser/serviceBusMessageBatch.js.map +1 -1
  47. package/dist/browser/serviceBusRuleManager.js +39 -15
  48. package/dist/browser/serviceBusRuleManager.js.map +1 -1
  49. package/dist/browser/session/messageSession.js +130 -25
  50. package/dist/browser/session/messageSession.js.map +1 -1
  51. package/dist/browser/util/atomXmlHelper.js +4 -5
  52. package/dist/browser/util/atomXmlHelper.js.map +1 -1
  53. package/dist/browser/util/compat/httpHeaders.js +1 -0
  54. package/dist/browser/util/compat/httpHeaders.js.map +1 -1
  55. package/dist/browser/util/constants.js +1 -1
  56. package/dist/browser/util/constants.js.map +1 -1
  57. package/dist/browser/util/sasServiceClientCredentials.js +8 -0
  58. package/dist/browser/util/sasServiceClientCredentials.js.map +1 -1
  59. package/dist/browser/util/semaphore.js +6 -2
  60. package/dist/browser/util/semaphore.js.map +1 -1
  61. package/dist/browser/util/utils.js +5 -7
  62. package/dist/browser/util/utils.js.map +1 -1
  63. package/dist/commonjs/connectionContext.js +1 -2
  64. package/dist/commonjs/connectionContext.js.map +1 -1
  65. package/dist/commonjs/constructorHelpers.js +3 -4
  66. package/dist/commonjs/constructorHelpers.js.map +1 -1
  67. package/dist/commonjs/core/autoLockRenewer.js +9 -5
  68. package/dist/commonjs/core/autoLockRenewer.js.map +1 -1
  69. package/dist/commonjs/core/batchingReceiver.js +26 -18
  70. package/dist/commonjs/core/batchingReceiver.js.map +1 -1
  71. package/dist/commonjs/core/linkEntity.js +74 -13
  72. package/dist/commonjs/core/linkEntity.js.map +1 -1
  73. package/dist/commonjs/core/managementClient.js +48 -48
  74. package/dist/commonjs/core/managementClient.js.map +1 -1
  75. package/dist/commonjs/core/messageReceiver.js +41 -14
  76. package/dist/commonjs/core/messageReceiver.js.map +1 -1
  77. package/dist/commonjs/core/messageSender.js +33 -10
  78. package/dist/commonjs/core/messageSender.js.map +1 -1
  79. package/dist/commonjs/core/receiverHelper.js +3 -2
  80. package/dist/commonjs/core/receiverHelper.js.map +1 -1
  81. package/dist/commonjs/core/shared.js +11 -4
  82. package/dist/commonjs/core/shared.js.map +1 -1
  83. package/dist/commonjs/core/streamingReceiver.js +74 -43
  84. package/dist/commonjs/core/streamingReceiver.js.map +1 -1
  85. package/dist/commonjs/diagnostics/instrumentServiceBusMessage.js +16 -8
  86. package/dist/commonjs/diagnostics/instrumentServiceBusMessage.js.map +1 -1
  87. package/dist/commonjs/receivers/receiver.js +68 -23
  88. package/dist/commonjs/receivers/receiver.js.map +1 -1
  89. package/dist/commonjs/receivers/receiverCommon.js +36 -21
  90. package/dist/commonjs/receivers/receiverCommon.js.map +1 -1
  91. package/dist/commonjs/receivers/sessionReceiver.js +69 -29
  92. package/dist/commonjs/receivers/sessionReceiver.js.map +1 -1
  93. package/dist/commonjs/sender.js +33 -11
  94. package/dist/commonjs/sender.js.map +1 -1
  95. package/dist/commonjs/serializers/queueResourceSerializer.js +9 -1
  96. package/dist/commonjs/serializers/queueResourceSerializer.js.map +1 -1
  97. package/dist/commonjs/serializers/ruleResourceSerializer.js +1 -2
  98. package/dist/commonjs/serializers/ruleResourceSerializer.js.map +1 -1
  99. package/dist/commonjs/serviceBusAtomManagementClient.js +181 -227
  100. package/dist/commonjs/serviceBusAtomManagementClient.js.map +1 -1
  101. package/dist/commonjs/serviceBusClient.js +31 -22
  102. package/dist/commonjs/serviceBusClient.js.map +1 -1
  103. package/dist/commonjs/serviceBusError.js +21 -1
  104. package/dist/commonjs/serviceBusError.js.map +1 -1
  105. package/dist/commonjs/serviceBusMessage.js +208 -12
  106. package/dist/commonjs/serviceBusMessage.js.map +1 -1
  107. package/dist/commonjs/serviceBusMessageBatch.js +32 -8
  108. package/dist/commonjs/serviceBusMessageBatch.js.map +1 -1
  109. package/dist/commonjs/serviceBusRuleManager.js +39 -15
  110. package/dist/commonjs/serviceBusRuleManager.js.map +1 -1
  111. package/dist/commonjs/session/messageSession.js +130 -25
  112. package/dist/commonjs/session/messageSession.js.map +1 -1
  113. package/dist/commonjs/tsdoc-metadata.json +11 -11
  114. package/dist/commonjs/util/atomXmlHelper.js +4 -5
  115. package/dist/commonjs/util/atomXmlHelper.js.map +1 -1
  116. package/dist/commonjs/util/compat/httpHeaders.js +1 -0
  117. package/dist/commonjs/util/compat/httpHeaders.js.map +1 -1
  118. package/dist/commonjs/util/constants.js +1 -1
  119. package/dist/commonjs/util/constants.js.map +1 -1
  120. package/dist/commonjs/util/runtimeInfo.js +2 -2
  121. package/dist/commonjs/util/runtimeInfo.js.map +1 -1
  122. package/dist/commonjs/util/sasServiceClientCredentials.js +8 -0
  123. package/dist/commonjs/util/sasServiceClientCredentials.js.map +1 -1
  124. package/dist/commonjs/util/semaphore.js +6 -2
  125. package/dist/commonjs/util/semaphore.js.map +1 -1
  126. package/dist/commonjs/util/utils.js +5 -7
  127. package/dist/commonjs/util/utils.js.map +1 -1
  128. package/dist/esm/connectionContext.js +1 -2
  129. package/dist/esm/connectionContext.js.map +1 -1
  130. package/dist/esm/constructorHelpers.js +3 -4
  131. package/dist/esm/constructorHelpers.js.map +1 -1
  132. package/dist/esm/core/autoLockRenewer.js +9 -5
  133. package/dist/esm/core/autoLockRenewer.js.map +1 -1
  134. package/dist/esm/core/batchingReceiver.js +26 -18
  135. package/dist/esm/core/batchingReceiver.js.map +1 -1
  136. package/dist/esm/core/linkEntity.js +74 -13
  137. package/dist/esm/core/linkEntity.js.map +1 -1
  138. package/dist/esm/core/managementClient.js +48 -48
  139. package/dist/esm/core/managementClient.js.map +1 -1
  140. package/dist/esm/core/messageReceiver.js +41 -14
  141. package/dist/esm/core/messageReceiver.js.map +1 -1
  142. package/dist/esm/core/messageSender.js +33 -10
  143. package/dist/esm/core/messageSender.js.map +1 -1
  144. package/dist/esm/core/receiverHelper.js +3 -2
  145. package/dist/esm/core/receiverHelper.js.map +1 -1
  146. package/dist/esm/core/shared.js +11 -4
  147. package/dist/esm/core/shared.js.map +1 -1
  148. package/dist/esm/core/streamingReceiver.js +74 -43
  149. package/dist/esm/core/streamingReceiver.js.map +1 -1
  150. package/dist/esm/diagnostics/instrumentServiceBusMessage.js +16 -8
  151. package/dist/esm/diagnostics/instrumentServiceBusMessage.js.map +1 -1
  152. package/dist/esm/receivers/receiver.js +68 -23
  153. package/dist/esm/receivers/receiver.js.map +1 -1
  154. package/dist/esm/receivers/receiverCommon.js +36 -21
  155. package/dist/esm/receivers/receiverCommon.js.map +1 -1
  156. package/dist/esm/receivers/sessionReceiver.js +69 -29
  157. package/dist/esm/receivers/sessionReceiver.js.map +1 -1
  158. package/dist/esm/sender.js +33 -11
  159. package/dist/esm/sender.js.map +1 -1
  160. package/dist/esm/serializers/queueResourceSerializer.js +9 -1
  161. package/dist/esm/serializers/queueResourceSerializer.js.map +1 -1
  162. package/dist/esm/serializers/ruleResourceSerializer.js +1 -2
  163. package/dist/esm/serializers/ruleResourceSerializer.js.map +1 -1
  164. package/dist/esm/serviceBusAtomManagementClient.js +181 -228
  165. package/dist/esm/serviceBusAtomManagementClient.js.map +1 -1
  166. package/dist/esm/serviceBusClient.js +31 -22
  167. package/dist/esm/serviceBusClient.js.map +1 -1
  168. package/dist/esm/serviceBusError.js +21 -1
  169. package/dist/esm/serviceBusError.js.map +1 -1
  170. package/dist/esm/serviceBusMessage.js +208 -13
  171. package/dist/esm/serviceBusMessage.js.map +1 -1
  172. package/dist/esm/serviceBusMessageBatch.js +32 -8
  173. package/dist/esm/serviceBusMessageBatch.js.map +1 -1
  174. package/dist/esm/serviceBusRuleManager.js +39 -15
  175. package/dist/esm/serviceBusRuleManager.js.map +1 -1
  176. package/dist/esm/session/messageSession.js +130 -25
  177. package/dist/esm/session/messageSession.js.map +1 -1
  178. package/dist/esm/util/atomXmlHelper.js +4 -5
  179. package/dist/esm/util/atomXmlHelper.js.map +1 -1
  180. package/dist/esm/util/compat/httpHeaders.js +1 -0
  181. package/dist/esm/util/compat/httpHeaders.js.map +1 -1
  182. package/dist/esm/util/constants.js +1 -1
  183. package/dist/esm/util/constants.js.map +1 -1
  184. package/dist/esm/util/runtimeInfo.js +1 -1
  185. package/dist/esm/util/runtimeInfo.js.map +1 -1
  186. package/dist/esm/util/sasServiceClientCredentials.js +8 -0
  187. package/dist/esm/util/sasServiceClientCredentials.js.map +1 -1
  188. package/dist/esm/util/semaphore.js +6 -2
  189. package/dist/esm/util/semaphore.js.map +1 -1
  190. package/dist/esm/util/utils.js +5 -7
  191. package/dist/esm/util/utils.js.map +1 -1
  192. package/dist/react-native/connectionContext.js +1 -2
  193. package/dist/react-native/connectionContext.js.map +1 -1
  194. package/dist/react-native/constructorHelpers.js +3 -4
  195. package/dist/react-native/constructorHelpers.js.map +1 -1
  196. package/dist/react-native/core/autoLockRenewer.js +9 -5
  197. package/dist/react-native/core/autoLockRenewer.js.map +1 -1
  198. package/dist/react-native/core/batchingReceiver.js +26 -18
  199. package/dist/react-native/core/batchingReceiver.js.map +1 -1
  200. package/dist/react-native/core/linkEntity.js +74 -13
  201. package/dist/react-native/core/linkEntity.js.map +1 -1
  202. package/dist/react-native/core/managementClient.js +48 -48
  203. package/dist/react-native/core/managementClient.js.map +1 -1
  204. package/dist/react-native/core/messageReceiver.js +41 -14
  205. package/dist/react-native/core/messageReceiver.js.map +1 -1
  206. package/dist/react-native/core/messageSender.js +33 -10
  207. package/dist/react-native/core/messageSender.js.map +1 -1
  208. package/dist/react-native/core/receiverHelper.js +3 -2
  209. package/dist/react-native/core/receiverHelper.js.map +1 -1
  210. package/dist/react-native/core/shared.js +11 -4
  211. package/dist/react-native/core/shared.js.map +1 -1
  212. package/dist/react-native/core/streamingReceiver.js +74 -43
  213. package/dist/react-native/core/streamingReceiver.js.map +1 -1
  214. package/dist/react-native/diagnostics/instrumentServiceBusMessage.js +16 -8
  215. package/dist/react-native/diagnostics/instrumentServiceBusMessage.js.map +1 -1
  216. package/dist/react-native/receivers/receiver.js +68 -23
  217. package/dist/react-native/receivers/receiver.js.map +1 -1
  218. package/dist/react-native/receivers/receiverCommon.js +36 -21
  219. package/dist/react-native/receivers/receiverCommon.js.map +1 -1
  220. package/dist/react-native/receivers/sessionReceiver.js +69 -29
  221. package/dist/react-native/receivers/sessionReceiver.js.map +1 -1
  222. package/dist/react-native/sender.js +33 -11
  223. package/dist/react-native/sender.js.map +1 -1
  224. package/dist/react-native/serializers/queueResourceSerializer.js +9 -1
  225. package/dist/react-native/serializers/queueResourceSerializer.js.map +1 -1
  226. package/dist/react-native/serializers/ruleResourceSerializer.js +1 -2
  227. package/dist/react-native/serializers/ruleResourceSerializer.js.map +1 -1
  228. package/dist/react-native/serviceBusAtomManagementClient.js +181 -228
  229. package/dist/react-native/serviceBusAtomManagementClient.js.map +1 -1
  230. package/dist/react-native/serviceBusClient.js +31 -22
  231. package/dist/react-native/serviceBusClient.js.map +1 -1
  232. package/dist/react-native/serviceBusError.js +21 -1
  233. package/dist/react-native/serviceBusError.js.map +1 -1
  234. package/dist/react-native/serviceBusMessage.js +208 -13
  235. package/dist/react-native/serviceBusMessage.js.map +1 -1
  236. package/dist/react-native/serviceBusMessageBatch.js +32 -8
  237. package/dist/react-native/serviceBusMessageBatch.js.map +1 -1
  238. package/dist/react-native/serviceBusRuleManager.js +39 -15
  239. package/dist/react-native/serviceBusRuleManager.js.map +1 -1
  240. package/dist/react-native/session/messageSession.js +130 -25
  241. package/dist/react-native/session/messageSession.js.map +1 -1
  242. package/dist/react-native/util/atomXmlHelper.js +4 -5
  243. package/dist/react-native/util/atomXmlHelper.js.map +1 -1
  244. package/dist/react-native/util/compat/httpHeaders.js +1 -0
  245. package/dist/react-native/util/compat/httpHeaders.js.map +1 -1
  246. package/dist/react-native/util/constants.js +1 -1
  247. package/dist/react-native/util/constants.js.map +1 -1
  248. package/dist/react-native/util/sasServiceClientCredentials.js +8 -0
  249. package/dist/react-native/util/sasServiceClientCredentials.js.map +1 -1
  250. package/dist/react-native/util/semaphore.js +6 -2
  251. package/dist/react-native/util/semaphore.js.map +1 -1
  252. package/dist/react-native/util/utils.js +5 -7
  253. package/dist/react-native/util/utils.js.map +1 -1
  254. package/package.json +38 -38
@@ -40,12 +40,11 @@ function setCustomEndpointAddress(config, customEndpointAddress) {
40
40
  *
41
41
  */
42
42
  export function createConnectionContext(connectionString, credential, options) {
43
- var _a, _b;
44
43
  const config = ConnectionConfig.create(connectionString);
45
- config.webSocket = (_a = options === null || options === void 0 ? void 0 : options.webSocketOptions) === null || _a === void 0 ? void 0 : _a.webSocket;
44
+ config.webSocket = options?.webSocketOptions?.webSocket;
46
45
  config.webSocketEndpointPath = "$servicebus/websocket";
47
- config.webSocketConstructorOptions = (_b = options === null || options === void 0 ? void 0 : options.webSocketOptions) === null || _b === void 0 ? void 0 : _b.webSocketConstructorOptions;
48
- if (options === null || options === void 0 ? void 0 : options.customEndpointAddress) {
46
+ config.webSocketConstructorOptions = options?.webSocketOptions?.webSocketConstructorOptions;
47
+ if (options?.customEndpointAddress) {
49
48
  setCustomEndpointAddress(config, options.customEndpointAddress);
50
49
  }
51
50
  return ConnectionContext.create(config, credential, options);
@@ -1 +1 @@
1
- {"version":3,"file":"constructorHelpers.js","sourceRoot":"","sources":["../../src/constructorHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { RetryOptions, SasTokenProvider, WebSocketOptions } from \"@azure/core-amqp\";\nimport { ConnectionConfig, createSasTokenProvider } from \"@azure/core-amqp\";\nimport type { NamedKeyCredential, SASCredential, TokenCredential } from \"@azure/core-auth\";\nimport { isNamedKeyCredential, isSASCredential } from \"@azure/core-auth\";\nimport { ConnectionContext } from \"./connectionContext.js\";\nimport type { UserAgentPolicyOptions } from \"@azure/core-rest-pipeline\";\nimport type { ServiceBusConnectionStringProperties } from \"./util/connectionStringUtils.js\";\nimport { parseServiceBusConnectionString } from \"./util/connectionStringUtils.js\";\n\n/**\n * Describes the options that can be provided while creating the ServiceBusClient.\n *\n * - `webSocketOptions` : Options to configure the channelling of the AMQP connection over Web Sockets.\n * - `websocket` : The WebSocket constructor used to create an AMQP connection if you choose to make the connection\n * over a WebSocket.\n * - `webSocketConstructorOptions` : Options to pass to the Websocket constructor when you choose to make the connection\n * over a WebSocket.\n * - `retryOptions` : The retry options for all the operations on the client.\n * - `maxRetries` : The number of times the operation can be retried in case of a retryable error.\n * - `maxRetryDelayInMs`: The maximum delay between retries. Applicable only when performing exponential retries.\n * - `mode`: Which retry mode to apply, specified by the `RetryMode` enum. Options are `Exponential` and `Fixed`. Defaults to `Fixed`.\n * - `retryDelayInMs`: Amount of time to wait in milliseconds before making the next attempt. When `mode` is set to `Exponential`,\n * this is used to compute the exponentially increasing delays between retries. Default: 30000 milliseconds.\n * - `timeoutInMs`: Amount of time in milliseconds to wait before the operation times out. This will trigger a retry if there are any\n * retry attempts remaining. Minimum value: 60000 milliseconds.\n */\nexport interface ServiceBusClientOptions {\n /**\n * ID to identify this client. This can be used to correlate logs and exceptions.\n */\n identifier?: string;\n /**\n * A custom endpoint to use when connecting to the Service Bus service.\n * This can be useful when your network does not allow connecting to the\n * standard Azure Service Bus endpoint address, but does allow connecting\n * through an intermediary.\n *\n * Example: \"https://my.custom.endpoint:100/\"\n */\n customEndpointAddress?: string;\n /**\n * Retry policy options that determine the mode, number of retries, retry interval etc.\n */\n retryOptions?: RetryOptions;\n /**\n * Options to configure the channelling of the AMQP connection over Web Sockets.\n */\n webSocketOptions?: WebSocketOptions;\n /**\n * Options for adding user agent details to outgoing requests.\n */\n userAgentOptions?: UserAgentPolicyOptions;\n}\n\n// TODO: extract parseEndpoint and setCustomEndpointAddress into core-amqp\n// ConnectionConfig so that it can be shared between Event Hubs and Service Bus\n/**\n * Parses the host, hostname, and port from an endpoint.\n * @param endpoint - And endpoint to parse.\n * @internal\n */\nexport function parseEndpoint(endpoint: string): { host: string; hostname: string; port?: string } {\n const hostMatch = endpoint.match(/.*:\\/\\/([^/]*)/);\n if (!hostMatch) {\n throw new TypeError(`Invalid endpoint missing host: ${endpoint}`);\n }\n\n const [, host] = hostMatch;\n const [hostname, port] = host.split(\":\");\n\n return { host, hostname, port };\n}\n/**\n * Updates the provided ConnectionConfig to use the custom endpoint address.\n * @param config - An existing connection configuration to be updated.\n * @param customEndpointAddress - The custom endpoint address to use.\n */\nfunction setCustomEndpointAddress(config: ConnectionConfig, customEndpointAddress: string): void {\n // The amqpHostname should match the host prior to using the custom endpoint.\n config.amqpHostname = config.host;\n const { hostname, port } = parseEndpoint(customEndpointAddress);\n // Since we specify the port separately, set host to the customEndpointAddress hostname.\n config.host = hostname;\n if (port) {\n config.port = parseInt(port, 10);\n }\n}\n\n/**\n * @internal\n *\n */\nexport function createConnectionContext(\n connectionString: string,\n credential: SasTokenProvider | TokenCredential,\n options: ServiceBusClientOptions,\n): ConnectionContext {\n const config = ConnectionConfig.create(connectionString);\n\n config.webSocket = options?.webSocketOptions?.webSocket;\n config.webSocketEndpointPath = \"$servicebus/websocket\";\n config.webSocketConstructorOptions = options?.webSocketOptions?.webSocketConstructorOptions;\n\n if (options?.customEndpointAddress) {\n setCustomEndpointAddress(config, options.customEndpointAddress);\n }\n\n return ConnectionContext.create(config, credential, options);\n}\n\n/**\n * @internal\n */\nexport function createConnectionContextForConnectionString(\n connectionString: string,\n options: ServiceBusClientOptions = {},\n): ConnectionContext {\n const parsed = parseServiceBusConnectionString(connectionString) as Required<\n | Pick<ServiceBusConnectionStringProperties, \"sharedAccessKey\" | \"sharedAccessKeyName\">\n | Pick<ServiceBusConnectionStringProperties, \"sharedAccessSignature\">\n >;\n const sasTokenProvider = createSasTokenProvider(parsed);\n return createConnectionContext(connectionString, sasTokenProvider, options);\n}\n\n/**\n *\n * @internal\n */\nexport function createConnectionContextForCredential(\n credential: TokenCredential | NamedKeyCredential | SASCredential,\n host: string,\n options: ServiceBusClientOptions = {},\n): ConnectionContext {\n if (typeof host !== \"string\") {\n throw new TypeError(\"`host` parameter is not a string\");\n }\n\n let tokenProvider: TokenCredential | SasTokenProvider;\n\n // host, credential and options based constructor was invoked\n if (!host.endsWith(\"/\")) {\n host += \"/\";\n }\n if (isNamedKeyCredential(credential) || isSASCredential(credential)) {\n tokenProvider = createSasTokenProvider(credential);\n } else {\n tokenProvider = credential;\n }\n const connectionString = `Endpoint=sb://${host};SharedAccessKeyName=defaultKeyName;SharedAccessKey=defaultKeyValue;`;\n return createConnectionContext(connectionString, tokenProvider, options);\n}\n\n/**\n * Parses a connection string and extracts the EntityPath named entity out.\n * @param connectionString - An entity specific Service Bus connection string.\n * @internal\n */\nexport function getEntityNameFromConnectionString(connectionString: string): string {\n const entityPathMatch = connectionString.match(/^.+EntityPath=(.+?);{0,1}$/);\n\n if (entityPathMatch != null && entityPathMatch.length === 2) {\n return entityPathMatch[1];\n } else {\n throw new Error(\"No entity name present in the connection string\");\n }\n}\n"]}
1
+ {"version":3,"file":"constructorHelpers.js","sourceRoot":"","sources":["../../src/constructorHelpers.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AA+ClF,0EAA0E;AAC1E,+EAA+E;AAC/E;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AACD;;;;GAIG;AACH,SAAS,wBAAwB,CAAC,MAAwB,EAAE,qBAA6B;IACvF,6EAA6E;IAC7E,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IAClC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAChE,wFAAwF;IACxF,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,gBAAwB,EACxB,UAA8C,EAC9C,OAAgC;IAEhC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAEzD,MAAM,CAAC,SAAS,GAAG,OAAO,EAAE,gBAAgB,EAAE,SAAS,CAAC;IACxD,MAAM,CAAC,qBAAqB,GAAG,uBAAuB,CAAC;IACvD,MAAM,CAAC,2BAA2B,GAAG,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,CAAC;IAE5F,IAAI,OAAO,EAAE,qBAAqB,EAAE,CAAC;QACnC,wBAAwB,CAAC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0CAA0C,CACxD,gBAAwB,EACxB,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,+BAA+B,CAAC,gBAAgB,CAG9D,CAAC;IACF,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,uBAAuB,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oCAAoC,CAClD,UAAgE,EAChE,IAAY,EACZ,UAAmC,EAAE;IAErC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,aAAiD,CAAC;IAEtD,6DAA6D;IAC7D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,IAAI,IAAI,GAAG,CAAC;IACd,CAAC;IACD,IAAI,oBAAoB,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QACpE,aAAa,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,UAAU,CAAC;IAC7B,CAAC;IACD,MAAM,gBAAgB,GAAG,iBAAiB,IAAI,sEAAsE,CAAC;IACrH,OAAO,uBAAuB,CAAC,gBAAgB,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAAC,gBAAwB;IACxE,MAAM,eAAe,GAAG,gBAAgB,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAE7E,IAAI,eAAe,IAAI,IAAI,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { RetryOptions, SasTokenProvider, WebSocketOptions } from \"@azure/core-amqp\";\nimport { ConnectionConfig, createSasTokenProvider } from \"@azure/core-amqp\";\nimport type { NamedKeyCredential, SASCredential, TokenCredential } from \"@azure/core-auth\";\nimport { isNamedKeyCredential, isSASCredential } from \"@azure/core-auth\";\nimport { ConnectionContext } from \"./connectionContext.js\";\nimport type { UserAgentPolicyOptions } from \"@azure/core-rest-pipeline\";\nimport type { ServiceBusConnectionStringProperties } from \"./util/connectionStringUtils.js\";\nimport { parseServiceBusConnectionString } from \"./util/connectionStringUtils.js\";\n\n/**\n * Describes the options that can be provided while creating the ServiceBusClient.\n *\n * - `webSocketOptions` : Options to configure the channelling of the AMQP connection over Web Sockets.\n * - `websocket` : The WebSocket constructor used to create an AMQP connection if you choose to make the connection\n * over a WebSocket.\n * - `webSocketConstructorOptions` : Options to pass to the Websocket constructor when you choose to make the connection\n * over a WebSocket.\n * - `retryOptions` : The retry options for all the operations on the client.\n * - `maxRetries` : The number of times the operation can be retried in case of a retryable error.\n * - `maxRetryDelayInMs`: The maximum delay between retries. Applicable only when performing exponential retries.\n * - `mode`: Which retry mode to apply, specified by the `RetryMode` enum. Options are `Exponential` and `Fixed`. Defaults to `Fixed`.\n * - `retryDelayInMs`: Amount of time to wait in milliseconds before making the next attempt. When `mode` is set to `Exponential`,\n * this is used to compute the exponentially increasing delays between retries. Default: 30000 milliseconds.\n * - `timeoutInMs`: Amount of time in milliseconds to wait before the operation times out. This will trigger a retry if there are any\n * retry attempts remaining. Minimum value: 60000 milliseconds.\n */\nexport interface ServiceBusClientOptions {\n /**\n * ID to identify this client. This can be used to correlate logs and exceptions.\n */\n identifier?: string;\n /**\n * A custom endpoint to use when connecting to the Service Bus service.\n * This can be useful when your network does not allow connecting to the\n * standard Azure Service Bus endpoint address, but does allow connecting\n * through an intermediary.\n *\n * Example: \"https://my.custom.endpoint:100/\"\n */\n customEndpointAddress?: string;\n /**\n * Retry policy options that determine the mode, number of retries, retry interval etc.\n */\n retryOptions?: RetryOptions;\n /**\n * Options to configure the channelling of the AMQP connection over Web Sockets.\n */\n webSocketOptions?: WebSocketOptions;\n /**\n * Options for adding user agent details to outgoing requests.\n */\n userAgentOptions?: UserAgentPolicyOptions;\n}\n\n// TODO: extract parseEndpoint and setCustomEndpointAddress into core-amqp\n// ConnectionConfig so that it can be shared between Event Hubs and Service Bus\n/**\n * Parses the host, hostname, and port from an endpoint.\n * @param endpoint - And endpoint to parse.\n * @internal\n */\nexport function parseEndpoint(endpoint: string): { host: string; hostname: string; port?: string } {\n const hostMatch = endpoint.match(/.*:\\/\\/([^/]*)/);\n if (!hostMatch) {\n throw new TypeError(`Invalid endpoint missing host: ${endpoint}`);\n }\n\n const [, host] = hostMatch;\n const [hostname, port] = host.split(\":\");\n\n return { host, hostname, port };\n}\n/**\n * Updates the provided ConnectionConfig to use the custom endpoint address.\n * @param config - An existing connection configuration to be updated.\n * @param customEndpointAddress - The custom endpoint address to use.\n */\nfunction setCustomEndpointAddress(config: ConnectionConfig, customEndpointAddress: string): void {\n // The amqpHostname should match the host prior to using the custom endpoint.\n config.amqpHostname = config.host;\n const { hostname, port } = parseEndpoint(customEndpointAddress);\n // Since we specify the port separately, set host to the customEndpointAddress hostname.\n config.host = hostname;\n if (port) {\n config.port = parseInt(port, 10);\n }\n}\n\n/**\n * @internal\n *\n */\nexport function createConnectionContext(\n connectionString: string,\n credential: SasTokenProvider | TokenCredential,\n options: ServiceBusClientOptions,\n): ConnectionContext {\n const config = ConnectionConfig.create(connectionString);\n\n config.webSocket = options?.webSocketOptions?.webSocket;\n config.webSocketEndpointPath = \"$servicebus/websocket\";\n config.webSocketConstructorOptions = options?.webSocketOptions?.webSocketConstructorOptions;\n\n if (options?.customEndpointAddress) {\n setCustomEndpointAddress(config, options.customEndpointAddress);\n }\n\n return ConnectionContext.create(config, credential, options);\n}\n\n/**\n * @internal\n */\nexport function createConnectionContextForConnectionString(\n connectionString: string,\n options: ServiceBusClientOptions = {},\n): ConnectionContext {\n const parsed = parseServiceBusConnectionString(connectionString) as Required<\n | Pick<ServiceBusConnectionStringProperties, \"sharedAccessKey\" | \"sharedAccessKeyName\">\n | Pick<ServiceBusConnectionStringProperties, \"sharedAccessSignature\">\n >;\n const sasTokenProvider = createSasTokenProvider(parsed);\n return createConnectionContext(connectionString, sasTokenProvider, options);\n}\n\n/**\n *\n * @internal\n */\nexport function createConnectionContextForCredential(\n credential: TokenCredential | NamedKeyCredential | SASCredential,\n host: string,\n options: ServiceBusClientOptions = {},\n): ConnectionContext {\n if (typeof host !== \"string\") {\n throw new TypeError(\"`host` parameter is not a string\");\n }\n\n let tokenProvider: TokenCredential | SasTokenProvider;\n\n // host, credential and options based constructor was invoked\n if (!host.endsWith(\"/\")) {\n host += \"/\";\n }\n if (isNamedKeyCredential(credential) || isSASCredential(credential)) {\n tokenProvider = createSasTokenProvider(credential);\n } else {\n tokenProvider = credential;\n }\n const connectionString = `Endpoint=sb://${host};SharedAccessKeyName=defaultKeyName;SharedAccessKey=defaultKeyValue;`;\n return createConnectionContext(connectionString, tokenProvider, options);\n}\n\n/**\n * Parses a connection string and extracts the EntityPath named entity out.\n * @param connectionString - An entity specific Service Bus connection string.\n * @internal\n */\nexport function getEntityNameFromConnectionString(connectionString: string): string {\n const entityPathMatch = connectionString.match(/^.+EntityPath=(.+?);{0,1}$/);\n\n if (entityPathMatch != null && entityPathMatch.length === 2) {\n return entityPathMatch[1];\n } else {\n throw new Error(\"No entity name present in the connection string\");\n }\n}\n"]}
@@ -8,14 +8,18 @@ import { calculateRenewAfterDuration } from "../util/utils.js";
8
8
  * @internal
9
9
  */
10
10
  export class LockRenewer {
11
+ _context;
12
+ _maxAutoRenewDurationInMs;
13
+ /**
14
+ * A map of link names to individual maps for each
15
+ * link that map a message ID to its auto-renewal timer.
16
+ */
17
+ _messageRenewLockTimers = new Map();
18
+ // just here for make unit testing a bit easier.
19
+ _calculateRenewAfterDuration;
11
20
  constructor(_context, _maxAutoRenewDurationInMs) {
12
21
  this._context = _context;
13
22
  this._maxAutoRenewDurationInMs = _maxAutoRenewDurationInMs;
14
- /**
15
- * A map of link names to individual maps for each
16
- * link that map a message ID to its auto-renewal timer.
17
- */
18
- this._messageRenewLockTimers = new Map();
19
23
  this._calculateRenewAfterDuration = calculateRenewAfterDuration;
20
24
  }
21
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"autoLockRenewer.js","sourceRoot":"","sources":["../../../src/core/autoLockRenewer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ConnectionContext } from \"../connectionContext.js\";\nimport { receiverLogger as logger } from \"../log.js\";\nimport type { ServiceBusMessageImpl } from \"../serviceBusMessage.js\";\nimport { calculateRenewAfterDuration } from \"../util/utils.js\";\nimport type { LinkEntity } from \"./linkEntity.js\";\nimport type { OnErrorNoContext } from \"./messageReceiver.js\";\n\n/**\n * @internal\n */\nexport type RenewableMessageProperties = Readonly<\n Pick<ServiceBusMessageImpl, \"lockToken\" | \"messageId\">\n> &\n // updated when we renew the lock\n Pick<ServiceBusMessageImpl, \"lockedUntilUtc\">;\n\n/**\n * @internal\n */\ntype MinimalLink = Pick<LinkEntity<any>, \"name\" | \"logPrefix\" | \"entityPath\">;\n\n/**\n * Tracks locks for messages, renewing until a configurable duration.\n *\n * @internal\n */\nexport class LockRenewer {\n /**\n * A map of link names to individual maps for each\n * link that map a message ID to its auto-renewal timer.\n */\n private _messageRenewLockTimers = new Map<string, Map<string, NodeJS.Timeout | undefined>>();\n\n // just here for make unit testing a bit easier.\n private _calculateRenewAfterDuration: typeof calculateRenewAfterDuration;\n\n constructor(\n private _context: Pick<ConnectionContext, \"getManagementClient\">,\n private _maxAutoRenewDurationInMs: number,\n ) {\n this._calculateRenewAfterDuration = calculateRenewAfterDuration;\n }\n\n /**\n * Creates an AutoLockRenewer.\n *\n * @param linkEntity - Your link entity instance (probably 'this')\n * @param context - The connection context for your link entity (probably 'this._context')\n * @param options - The ReceiveOptions passed through to your message receiver.\n * @returns if the lock mode is peek lock (or if is unspecified, thus defaulting to peekLock)\n * and the options.maxAutoLockRenewalDurationInMs is greater than 0..Otherwise, returns undefined.\n */\n static create(\n context: Pick<ConnectionContext, \"getManagementClient\">,\n maxAutoRenewLockDurationInMs: number,\n receiveMode: \"peekLock\" | \"receiveAndDelete\",\n ): LockRenewer | undefined {\n if (receiveMode !== \"peekLock\") {\n return undefined;\n }\n\n if (maxAutoRenewLockDurationInMs <= 0) {\n return undefined;\n }\n\n return new LockRenewer(context, maxAutoRenewLockDurationInMs);\n }\n\n /**\n * Cancels all pending lock renewals for messages on given link and removes all entries from our internal cache.\n */\n stopAll(linkEntity: MinimalLink): void {\n logger.verbose(\n `${linkEntity.logPrefix} Clearing message renew lock timers for all the active messages.`,\n );\n\n const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name);\n\n if (messagesForLink == null) {\n return;\n }\n\n for (const messageId of messagesForLink.keys()) {\n this._stopAndRemoveById(linkEntity, messagesForLink, messageId);\n }\n\n this._messageRenewLockTimers.delete(linkEntity.name);\n }\n\n /**\n * Stops lock renewal for a single message.\n *\n * @param bMessage - The message whose lock renewal we will stop.\n */\n stop(linkEntity: MinimalLink, bMessage: RenewableMessageProperties): void {\n const messageId = bMessage.messageId as string;\n\n const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name);\n\n if (messagesForLink == null) {\n return;\n }\n\n this._stopAndRemoveById(linkEntity, messagesForLink, messageId);\n }\n\n /**\n * Starts lock renewal for a single message.\n *\n * @param bMessage - The message whose lock renewal we will start.\n */\n start(\n linkEntity: MinimalLink,\n bMessage: RenewableMessageProperties,\n onError: OnErrorNoContext,\n ): void {\n try {\n const logPrefix = linkEntity.logPrefix;\n\n if (bMessage.lockToken == null) {\n throw new Error(\n `Can't start auto lock renewal for message with message id '${bMessage.messageId}' since it does not have a lock token.`,\n );\n }\n\n const lockToken = bMessage.lockToken;\n const linkMessageMap = this._getOrCreateMapForLink(linkEntity);\n // - We need to renew locks before they expire by looking at bMessage.lockedUntilUtc.\n // - This autorenewal needs to happen **NO MORE** than maxAutoRenewDurationInMs\n // - We should be able to clear the renewal timer when the user's message handler\n // is done (whether it succeeds or fails).\n // Setting the messageId with undefined value in the linkMessageMap because we\n // track state by checking the presence of messageId in the map. It is removed from the map\n // when an attempt is made to settle the message (either by the user or by the sdk) OR\n // when the execution of user's message handler completes.\n linkMessageMap.set(bMessage.messageId as string, undefined);\n\n logger.verbose(\n `${logPrefix} message with id '${\n bMessage.messageId\n }' is locked until ${bMessage.lockedUntilUtc!.toString()}.`,\n );\n const totalAutoLockRenewDuration = Date.now() + this._maxAutoRenewDurationInMs;\n const totalAutoLockRenewDurationDate = new Date(totalAutoLockRenewDuration);\n logger.verbose(\n `${logPrefix} Total autolockrenew duration for message with id '${\n bMessage.messageId\n }' is: ${totalAutoLockRenewDurationDate.toString()}`,\n );\n\n const autoRenewLockTask = (): void => {\n const renewalNeededToMaintainLock =\n // if the lock expires _after_ our max auto-renew duration there's no reason to\n // spin up an auto-renewer - it's already held for the duration.\n totalAutoLockRenewDurationDate > bMessage.lockedUntilUtc!;\n\n if (!renewalNeededToMaintainLock) {\n logger.verbose(\n `${logPrefix} Autolockrenew not needed as message's lockedUntilUtc ${bMessage.lockedUntilUtc} is after the total autolockrenew duration ${totalAutoLockRenewDurationDate} for message with messageId '${bMessage.messageId}'. Hence we will stop the autoLockRenewTask.`,\n );\n this.stop(linkEntity, bMessage);\n } else if (Date.now() >= totalAutoLockRenewDuration) {\n // once we've exceeded the max amount of time we'll renew we can stop.\n logger.verbose(\n `${logPrefix} Current time ${new Date()} exceeds the total autolockrenew duration ${totalAutoLockRenewDurationDate} for message with messageId '${\n bMessage.messageId\n }'. Hence we will stop the autoLockRenewTask.`,\n );\n this.stop(linkEntity, bMessage);\n } else {\n if (linkMessageMap.has(bMessage.messageId as string)) {\n // TODO: We can run into problems with clock skew between the client and the server.\n // It would be better to calculate the duration based on the \"lockDuration\" property\n // of the queue. However, we do not have the management plane of the client ready for\n // now. Hence we rely on the lockedUntilUtc property on the message set by ServiceBus.\n const amount = this._calculateRenewAfterDuration(bMessage.lockedUntilUtc!);\n\n logger.verbose(\n `${logPrefix} Sleeping for ${amount} milliseconds while renewing the lock for message with id '${bMessage.messageId}'`,\n );\n // Setting the value of the messageId to the actual timer. This will be cleared when\n // an attempt is made to settle the message (either by the user or by the sdk) OR\n // when the execution of user's message handler completes.\n const autoRenewTimer = setTimeout(async () => {\n try {\n logger.verbose(\n `${logPrefix} Attempting to renew the lock for message with id '${bMessage.messageId}'.`,\n );\n\n bMessage.lockedUntilUtc = await this._context\n .getManagementClient(linkEntity.entityPath)\n .renewLock(lockToken, {\n associatedLinkName: linkEntity.name,\n });\n logger.verbose(\n `${logPrefix} Successfully renewed the lock for message with id '${bMessage.messageId}'. Starting next auto-lock-renew cycle for message.`,\n );\n\n autoRenewLockTask();\n } catch (err: any) {\n logger.logError(\n err,\n `${logPrefix} An error occurred while auto renewing the message lock '${bMessage.lockToken}' for message with id '${bMessage.messageId}'`,\n );\n onError(err);\n }\n }, amount);\n\n // Prevent the active Timer from keeping the Node.js event loop active.\n if (typeof autoRenewTimer.unref === \"function\") {\n autoRenewTimer.unref();\n }\n\n linkMessageMap.set(bMessage.messageId as string, autoRenewTimer);\n } else {\n logger.verbose(\n `${logPrefix} Looks like the message lock renew timer has already been cleared for message with id '${bMessage.messageId}'.`,\n );\n }\n }\n };\n\n // start\n autoRenewLockTask();\n } catch (err: any) {\n onError(err);\n }\n }\n\n private _getOrCreateMapForLink(linkEntity: MinimalLink): Map<string, NodeJS.Timeout | undefined> {\n if (!this._messageRenewLockTimers.has(linkEntity.name)) {\n this._messageRenewLockTimers.set(\n linkEntity.name,\n new Map<string, NodeJS.Timeout | undefined>(),\n );\n }\n\n return this._messageRenewLockTimers.get(linkEntity.name)!;\n }\n\n private _stopAndRemoveById(\n linkEntity: MinimalLink,\n linkMessageMap: Map<string, NodeJS.Timeout | undefined>,\n messageId: string | undefined,\n ): void {\n if (messageId == null) {\n throw new Error(\"Failed to stop auto lock renewal - no message ID\");\n }\n\n // TODO: messageId doesn't actually need to be unique. Perhaps we should use lockToken\n // instead?\n if (linkMessageMap.has(messageId)) {\n clearTimeout(linkMessageMap.get(messageId) as NodeJS.Timeout);\n logger.verbose(\n `${linkEntity.logPrefix} Cleared the message renew lock timer for message with id '${messageId}'.`,\n );\n linkMessageMap.delete(messageId);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"autoLockRenewer.js","sourceRoot":"","sources":["../../../src/core/autoLockRenewer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ConnectionContext } from \"../connectionContext.js\";\nimport { receiverLogger as logger } from \"../log.js\";\nimport type { ServiceBusMessageImpl } from \"../serviceBusMessage.js\";\nimport { calculateRenewAfterDuration } from \"../util/utils.js\";\nimport type { LinkEntity } from \"./linkEntity.js\";\nimport type { OnErrorNoContext } from \"./messageReceiver.js\";\n\n/**\n * @internal\n */\nexport type RenewableMessageProperties = Readonly<\n Pick<ServiceBusMessageImpl, \"lockToken\" | \"messageId\">\n> &\n // updated when we renew the lock\n Pick<ServiceBusMessageImpl, \"lockedUntilUtc\">;\n\n/**\n * @internal\n */\ntype MinimalLink = Pick<LinkEntity<any>, \"name\" | \"logPrefix\" | \"entityPath\">;\n\n/**\n * Tracks locks for messages, renewing until a configurable duration.\n *\n * @internal\n */\nexport class LockRenewer {\n /**\n * A map of link names to individual maps for each\n * link that map a message ID to its auto-renewal timer.\n */\n private _messageRenewLockTimers = new Map<string, Map<string, NodeJS.Timeout | undefined>>();\n\n // just here for make unit testing a bit easier.\n private _calculateRenewAfterDuration: typeof calculateRenewAfterDuration;\n\n constructor(\n private _context: Pick<ConnectionContext, \"getManagementClient\">,\n private _maxAutoRenewDurationInMs: number,\n ) {\n this._calculateRenewAfterDuration = calculateRenewAfterDuration;\n }\n\n /**\n * Creates an AutoLockRenewer.\n *\n * @param linkEntity - Your link entity instance (probably 'this')\n * @param context - The connection context for your link entity (probably 'this._context')\n * @param options - The ReceiveOptions passed through to your message receiver.\n * @returns if the lock mode is peek lock (or if is unspecified, thus defaulting to peekLock)\n * and the options.maxAutoLockRenewalDurationInMs is greater than 0..Otherwise, returns undefined.\n */\n static create(\n context: Pick<ConnectionContext, \"getManagementClient\">,\n maxAutoRenewLockDurationInMs: number,\n receiveMode: \"peekLock\" | \"receiveAndDelete\",\n ): LockRenewer | undefined {\n if (receiveMode !== \"peekLock\") {\n return undefined;\n }\n\n if (maxAutoRenewLockDurationInMs <= 0) {\n return undefined;\n }\n\n return new LockRenewer(context, maxAutoRenewLockDurationInMs);\n }\n\n /**\n * Cancels all pending lock renewals for messages on given link and removes all entries from our internal cache.\n */\n stopAll(linkEntity: MinimalLink): void {\n logger.verbose(\n `${linkEntity.logPrefix} Clearing message renew lock timers for all the active messages.`,\n );\n\n const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name);\n\n if (messagesForLink == null) {\n return;\n }\n\n for (const messageId of messagesForLink.keys()) {\n this._stopAndRemoveById(linkEntity, messagesForLink, messageId);\n }\n\n this._messageRenewLockTimers.delete(linkEntity.name);\n }\n\n /**\n * Stops lock renewal for a single message.\n *\n * @param bMessage - The message whose lock renewal we will stop.\n */\n stop(linkEntity: MinimalLink, bMessage: RenewableMessageProperties): void {\n const messageId = bMessage.messageId as string;\n\n const messagesForLink = this._messageRenewLockTimers.get(linkEntity.name);\n\n if (messagesForLink == null) {\n return;\n }\n\n this._stopAndRemoveById(linkEntity, messagesForLink, messageId);\n }\n\n /**\n * Starts lock renewal for a single message.\n *\n * @param bMessage - The message whose lock renewal we will start.\n */\n start(\n linkEntity: MinimalLink,\n bMessage: RenewableMessageProperties,\n onError: OnErrorNoContext,\n ): void {\n try {\n const logPrefix = linkEntity.logPrefix;\n\n if (bMessage.lockToken == null) {\n throw new Error(\n `Can't start auto lock renewal for message with message id '${bMessage.messageId}' since it does not have a lock token.`,\n );\n }\n\n const lockToken = bMessage.lockToken;\n const linkMessageMap = this._getOrCreateMapForLink(linkEntity);\n // - We need to renew locks before they expire by looking at bMessage.lockedUntilUtc.\n // - This autorenewal needs to happen **NO MORE** than maxAutoRenewDurationInMs\n // - We should be able to clear the renewal timer when the user's message handler\n // is done (whether it succeeds or fails).\n // Setting the messageId with undefined value in the linkMessageMap because we\n // track state by checking the presence of messageId in the map. It is removed from the map\n // when an attempt is made to settle the message (either by the user or by the sdk) OR\n // when the execution of user's message handler completes.\n linkMessageMap.set(bMessage.messageId as string, undefined);\n\n logger.verbose(\n `${logPrefix} message with id '${\n bMessage.messageId\n }' is locked until ${bMessage.lockedUntilUtc!.toString()}.`,\n );\n const totalAutoLockRenewDuration = Date.now() + this._maxAutoRenewDurationInMs;\n const totalAutoLockRenewDurationDate = new Date(totalAutoLockRenewDuration);\n logger.verbose(\n `${logPrefix} Total autolockrenew duration for message with id '${\n bMessage.messageId\n }' is: ${totalAutoLockRenewDurationDate.toString()}`,\n );\n\n const autoRenewLockTask = (): void => {\n const renewalNeededToMaintainLock =\n // if the lock expires _after_ our max auto-renew duration there's no reason to\n // spin up an auto-renewer - it's already held for the duration.\n totalAutoLockRenewDurationDate > bMessage.lockedUntilUtc!;\n\n if (!renewalNeededToMaintainLock) {\n logger.verbose(\n `${logPrefix} Autolockrenew not needed as message's lockedUntilUtc ${bMessage.lockedUntilUtc} is after the total autolockrenew duration ${totalAutoLockRenewDurationDate} for message with messageId '${bMessage.messageId}'. Hence we will stop the autoLockRenewTask.`,\n );\n this.stop(linkEntity, bMessage);\n } else if (Date.now() >= totalAutoLockRenewDuration) {\n // once we've exceeded the max amount of time we'll renew we can stop.\n logger.verbose(\n `${logPrefix} Current time ${new Date()} exceeds the total autolockrenew duration ${totalAutoLockRenewDurationDate} for message with messageId '${\n bMessage.messageId\n }'. Hence we will stop the autoLockRenewTask.`,\n );\n this.stop(linkEntity, bMessage);\n } else {\n if (linkMessageMap.has(bMessage.messageId as string)) {\n // TODO: We can run into problems with clock skew between the client and the server.\n // It would be better to calculate the duration based on the \"lockDuration\" property\n // of the queue. However, we do not have the management plane of the client ready for\n // now. Hence we rely on the lockedUntilUtc property on the message set by ServiceBus.\n const amount = this._calculateRenewAfterDuration(bMessage.lockedUntilUtc!);\n\n logger.verbose(\n `${logPrefix} Sleeping for ${amount} milliseconds while renewing the lock for message with id '${bMessage.messageId}'`,\n );\n // Setting the value of the messageId to the actual timer. This will be cleared when\n // an attempt is made to settle the message (either by the user or by the sdk) OR\n // when the execution of user's message handler completes.\n const autoRenewTimer = setTimeout(async () => {\n try {\n logger.verbose(\n `${logPrefix} Attempting to renew the lock for message with id '${bMessage.messageId}'.`,\n );\n\n bMessage.lockedUntilUtc = await this._context\n .getManagementClient(linkEntity.entityPath)\n .renewLock(lockToken, {\n associatedLinkName: linkEntity.name,\n });\n logger.verbose(\n `${logPrefix} Successfully renewed the lock for message with id '${bMessage.messageId}'. Starting next auto-lock-renew cycle for message.`,\n );\n\n autoRenewLockTask();\n } catch (err: any) {\n logger.logError(\n err,\n `${logPrefix} An error occurred while auto renewing the message lock '${bMessage.lockToken}' for message with id '${bMessage.messageId}'`,\n );\n onError(err);\n }\n }, amount);\n\n // Prevent the active Timer from keeping the Node.js event loop active.\n if (typeof autoRenewTimer.unref === \"function\") {\n autoRenewTimer.unref();\n }\n\n linkMessageMap.set(bMessage.messageId as string, autoRenewTimer);\n } else {\n logger.verbose(\n `${logPrefix} Looks like the message lock renew timer has already been cleared for message with id '${bMessage.messageId}'.`,\n );\n }\n }\n };\n\n // start\n autoRenewLockTask();\n } catch (err: any) {\n onError(err);\n }\n }\n\n private _getOrCreateMapForLink(linkEntity: MinimalLink): Map<string, NodeJS.Timeout | undefined> {\n if (!this._messageRenewLockTimers.has(linkEntity.name)) {\n this._messageRenewLockTimers.set(\n linkEntity.name,\n new Map<string, NodeJS.Timeout | undefined>(),\n );\n }\n\n return this._messageRenewLockTimers.get(linkEntity.name)!;\n }\n\n private _stopAndRemoveById(\n linkEntity: MinimalLink,\n linkMessageMap: Map<string, NodeJS.Timeout | undefined>,\n messageId: string | undefined,\n ): void {\n if (messageId == null) {\n throw new Error(\"Failed to stop auto lock renewal - no message ID\");\n }\n\n // TODO: messageId doesn't actually need to be unique. Perhaps we should use lockToken\n // instead?\n if (linkMessageMap.has(messageId)) {\n clearTimeout(linkMessageMap.get(messageId) as NodeJS.Timeout);\n logger.verbose(\n `${linkEntity.logPrefix} Cleared the message renew lock timer for message with id '${messageId}'.`,\n );\n linkMessageMap.delete(messageId);\n }\n }\n}\n"]}
@@ -24,18 +24,15 @@ export class BatchingReceiver extends MessageReceiver {
24
24
  * @param options - Options for how you'd like to connect.
25
25
  */
26
26
  constructor(identifier, connectionContext, entityPath, options) {
27
- var _a, _b;
28
27
  super(identifier, connectionContext, entityPath, "batching", options);
29
28
  this._batchingReceiverLite = new BatchingReceiverLite(connectionContext, entityPath, async (abortSignal) => {
30
29
  let lastError;
31
30
  const rcvrOptions = this._createReceiverOptions(false, {
32
31
  onError: (context) => {
33
- var _a;
34
- lastError = (_a = context === null || context === void 0 ? void 0 : context.receiver) === null || _a === void 0 ? void 0 : _a.error;
32
+ lastError = context?.receiver?.error;
35
33
  },
36
34
  onSessionError: (context) => {
37
- var _a;
38
- lastError = (_a = context === null || context === void 0 ? void 0 : context.session) === null || _a === void 0 ? void 0 : _a.error;
35
+ lastError = context?.session?.error;
39
36
  },
40
37
  onClose: async () => {
41
38
  /** Nothing to do here - the next call will just fail so they'll get an appropriate error from somewhere else. */
@@ -52,8 +49,9 @@ export class BatchingReceiver extends MessageReceiver {
52
49
  throw lastError;
53
50
  }
54
51
  return this.link;
55
- }, this.receiveMode, (_a = options.skipParsingBodyAsJson) !== null && _a !== void 0 ? _a : false, (_b = options.skipConvertingDate) !== null && _b !== void 0 ? _b : false);
52
+ }, this.receiveMode, options.skipParsingBodyAsJson ?? false, options.skipConvertingDate ?? false);
56
53
  }
54
+ _batchingReceiverLite;
57
55
  get isReceivingMessages() {
58
56
  return this._batchingReceiverLite.isReceivingMessages;
59
57
  }
@@ -81,9 +79,12 @@ export class BatchingReceiver extends MessageReceiver {
81
79
  async receive(maxMessageCount, maxWaitTimeInMs, maxTimeAfterFirstMessageInMs, options) {
82
80
  throwErrorIfConnectionClosed(this._context);
83
81
  try {
84
- const messages = await this._batchingReceiverLite.receiveMessages(Object.assign({ maxMessageCount,
82
+ const messages = await this._batchingReceiverLite.receiveMessages({
83
+ maxMessageCount,
85
84
  maxWaitTimeInMs,
86
- maxTimeAfterFirstMessageInMs }, options));
85
+ maxTimeAfterFirstMessageInMs,
86
+ ...options,
87
+ });
87
88
  if (this._lockRenewer) {
88
89
  for (const message of messages) {
89
90
  this._lockRenewer.start(this, message, (_error) => {
@@ -138,19 +139,28 @@ export function getRemainingWaitTimeInMsFn(maxWaitTimeInMs, maxTimeAfterFirstMes
138
139
  * @internal
139
140
  */
140
141
  export class BatchingReceiverLite {
142
+ _connectionContext;
143
+ entityPath;
144
+ _getCurrentReceiver;
145
+ _receiveMode;
146
+ // testing hook
147
+ _drainTimeoutInMs = receiveDrainTimeoutInMs;
141
148
  constructor(_connectionContext, entityPath, _getCurrentReceiver, _receiveMode, _skipParsingBodyAsJson, _skipConvertingDate) {
142
149
  this._connectionContext = _connectionContext;
143
150
  this.entityPath = entityPath;
144
151
  this._getCurrentReceiver = _getCurrentReceiver;
145
152
  this._receiveMode = _receiveMode;
146
- // testing hook
147
- this._drainTimeoutInMs = receiveDrainTimeoutInMs;
148
153
  this._createServiceBusMessage = (context) => {
149
154
  return new ServiceBusMessageImpl(context.message, context.delivery, true, this._receiveMode, _skipParsingBodyAsJson, _skipConvertingDate);
150
155
  };
151
156
  this._getRemainingWaitTimeInMsFn = (maxWaitTimeInMs, maxTimeAfterFirstMessageInMs) => getRemainingWaitTimeInMsFn(maxWaitTimeInMs, maxTimeAfterFirstMessageInMs);
152
157
  this.isReceivingMessages = false;
153
158
  }
159
+ _createServiceBusMessage;
160
+ _getRemainingWaitTimeInMsFn;
161
+ _closeHandler;
162
+ _finalAction;
163
+ isReceivingMessages;
154
164
  /**
155
165
  * Receives a set of messages,
156
166
  *
@@ -198,7 +208,7 @@ export class BatchingReceiverLite {
198
208
  resolve();
199
209
  }
200
210
  function removeListeners() {
201
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener("abort", onAbort);
211
+ abortSignal?.removeEventListener("abort", onAbort);
202
212
  receiver.removeListener(ReceiverEvents.receiverDrained, drainListener);
203
213
  }
204
214
  function onAbort() {
@@ -212,7 +222,7 @@ export class BatchingReceiverLite {
212
222
  resolve();
213
223
  }, timeToWaitInMs);
214
224
  receiver.once(ReceiverEvents.receiverDrained, drainListener);
215
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener("abort", onAbort);
225
+ abortSignal?.addEventListener("abort", onAbort);
216
226
  });
217
227
  receiver.drainCredit();
218
228
  logger.verbose(`${loggingPrefix} Draining leftover credits(${receiver.credit}), waiting for event_drained event, or timing out after ${timeToWaitInMs} milliseconds...`);
@@ -254,9 +264,8 @@ export class BatchingReceiverLite {
254
264
  });
255
265
  };
256
266
  const onError = (context) => {
257
- var _a, _b, _c;
258
- const eventType = ((_a = context.session) === null || _a === void 0 ? void 0 : _a.error) != null ? "session_error" : "receiver_error";
259
- let error = ((_b = context.session) === null || _b === void 0 ? void 0 : _b.error) || ((_c = context.receiver) === null || _c === void 0 ? void 0 : _c.error);
267
+ const eventType = context.session?.error != null ? "session_error" : "receiver_error";
268
+ let error = context.session?.error || context.receiver?.error;
260
269
  if (error) {
261
270
  error = translateServiceBusError(error);
262
271
  logger.logError(error, `${loggingPrefix} '${eventType}' event occurred. Received an error`);
@@ -336,9 +345,8 @@ export class BatchingReceiverLite {
336
345
  }
337
346
  };
338
347
  const onClose = async (context) => {
339
- var _a, _b, _c;
340
- const type = ((_a = context.session) === null || _a === void 0 ? void 0 : _a.error) != null ? "session_closed" : "receiver_closed";
341
- const error = ((_b = context.session) === null || _b === void 0 ? void 0 : _b.error) || ((_c = context.receiver) === null || _c === void 0 ? void 0 : _c.error);
348
+ const type = context.session?.error != null ? "session_closed" : "receiver_closed";
349
+ const error = context.session?.error || context.receiver?.error;
342
350
  if (error) {
343
351
  logger.logError(error, `${loggingPrefix} '${type}' event occurred. The associated error`);
344
352
  }
@@ -1 +1 @@
1
- {"version":3,"file":"batchingReceiver.js","sourceRoot":"","sources":["../../../src/core/batchingReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { receiverLogger as logger } from \"../log.js\";\nimport type {\n AmqpError,\n EventContext,\n OnAmqpEvent,\n Receiver as RheaPromiseReceiver,\n Session,\n} from \"rhea-promise\";\nimport { ReceiverEvents, SessionEvents } from \"rhea-promise\";\nimport { ServiceBusMessageImpl } from \"../serviceBusMessage.js\";\nimport type { OnAmqpEventAsPromise, ReceiveOptions } from \"./messageReceiver.js\";\nimport { MessageReceiver } from \"./messageReceiver.js\";\nimport type { ConnectionContext } from \"../connectionContext.js\";\nimport { throwErrorIfConnectionClosed } from \"../util/errors.js\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { checkAndRegisterWithAbortSignal } from \"../util/utils.js\";\nimport { receiveDrainTimeoutInMs } from \"../util/constants.js\";\nimport type { OperationOptionsBase } from \"../modelsToBeSharedWithEventHubs.js\";\nimport { toProcessingSpanOptions } from \"../diagnostics/instrumentServiceBusMessage.js\";\nimport type { ReceiveMode } from \"../models.js\";\nimport { ServiceBusError, translateServiceBusError } from \"../serviceBusError.js\";\nimport { tracingClient } from \"../diagnostics/tracing.js\";\n\n/**\n * Describes the batching receiver where the user can receive a specified number of messages for\n * a predefined time.\n * @internal\n */\nexport class BatchingReceiver extends MessageReceiver {\n /**\n * Instantiate a new BatchingReceiver.\n *\n * @param identifier - name to identify this receiver.\n * @param connectionContext - The client entity context.\n * @param options - Options for how you'd like to connect.\n */\n constructor(\n identifier: string,\n connectionContext: ConnectionContext,\n entityPath: string,\n options: ReceiveOptions,\n ) {\n super(identifier, connectionContext, entityPath, \"batching\", options);\n\n this._batchingReceiverLite = new BatchingReceiverLite(\n connectionContext,\n entityPath,\n async (abortSignal?: AbortSignalLike): Promise<MinimalReceiver | undefined> => {\n let lastError: Error | AmqpError | undefined;\n\n const rcvrOptions = this._createReceiverOptions(false, {\n onError: (context) => {\n lastError = context?.receiver?.error;\n },\n onSessionError: (context) => {\n lastError = context?.session?.error;\n },\n onClose: async () => {\n /** Nothing to do here - the next call will just fail so they'll get an appropriate error from somewhere else. */\n },\n onSessionClose: async () => {\n /** Nothing to do here - the next call will just fail so they'll get an appropriate error from somewhere else. */\n },\n onMessage: async () => {\n /** Nothing to do here - we don't add credits initially so we don't need to worry about handling any messages.*/\n },\n });\n\n await this._init(rcvrOptions, abortSignal);\n\n if (lastError != null) {\n throw lastError;\n }\n\n return this.link;\n },\n this.receiveMode,\n options.skipParsingBodyAsJson ?? false,\n options.skipConvertingDate ?? false,\n );\n }\n\n private _batchingReceiverLite: BatchingReceiverLite;\n\n get isReceivingMessages(): boolean {\n return this._batchingReceiverLite.isReceivingMessages;\n }\n\n /**\n * To be called when connection is disconnected to gracefully close ongoing receive request.\n * @param connectionError - The connection error if any.\n */\n async onDetached(connectionError?: AmqpError | Error): Promise<void> {\n await this.closeLink();\n\n if (connectionError == null) {\n connectionError = new Error(\n \"Unknown error occurred on the AMQP connection while receiving messages.\",\n );\n }\n\n this._batchingReceiverLite.terminate(connectionError);\n }\n\n /**\n * Receives a batch of messages from a ServiceBus Queue/Topic.\n * @param maxMessageCount - The maximum number of messages to receive.\n * In Peeklock mode, this number is capped at 2047 due to constraints of the underlying buffer.\n * @param maxWaitTimeInMs - The total wait time in milliseconds until which the receiver will attempt to receive specified number of messages.\n * @param maxTimeAfterFirstMessageInMs - The total amount of time to wait after the first message\n * has been received. Defaults to 1 second.\n * If this time elapses before the `maxMessageCount` is reached, then messages collected till then will be returned to the user.\n * @returns A promise that resolves with an array of Message objects.\n */\n async receive(\n maxMessageCount: number,\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n options: OperationOptionsBase,\n ): Promise<ServiceBusMessageImpl[]> {\n throwErrorIfConnectionClosed(this._context);\n try {\n const messages = await this._batchingReceiverLite.receiveMessages({\n maxMessageCount,\n maxWaitTimeInMs,\n maxTimeAfterFirstMessageInMs,\n ...options,\n });\n\n if (this._lockRenewer) {\n for (const message of messages) {\n this._lockRenewer.start(this, message, (_error) => {\n // the auto lock renewer already logs this in a detailed way. So this hook is mainly here\n // to potentially forward the error to the user (which we're not doing yet)\n });\n }\n }\n\n return messages;\n } catch (error: any) {\n logger.logError(error, \"[%s] Rejecting receiveMessages()\", this.logPrefix);\n throw error;\n }\n }\n\n static create(\n clientId: string,\n context: ConnectionContext,\n entityPath: string,\n options: ReceiveOptions,\n ): BatchingReceiver {\n throwErrorIfConnectionClosed(context);\n const bReceiver = new BatchingReceiver(clientId, context, entityPath, options);\n context.messageReceivers[bReceiver.name] = bReceiver;\n return bReceiver;\n }\n\n protected removeLinkFromContext(): void {\n delete this._context.messageReceivers[this.name];\n }\n}\n\n/**\n * Gets a function that returns the smaller of the two timeouts,\n * taking into account elapsed time from when getRemainingWaitTimeInMsFn\n * was called.\n *\n * @param maxWaitTimeInMs - Maximum time to wait for the first message\n * @param maxTimeAfterFirstMessageInMs - Maximum time to wait after the first message before completing the receive.\n *\n * @internal\n */\nexport function getRemainingWaitTimeInMsFn(\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n): () => number {\n const startTimeMs = Date.now();\n\n return () => {\n const remainingTimeMs = maxWaitTimeInMs - (Date.now() - startTimeMs);\n\n if (remainingTimeMs < 0) {\n return 0;\n }\n\n return Math.min(remainingTimeMs, maxTimeAfterFirstMessageInMs);\n };\n}\n\n/**\n * Useful interface that mimics EventEmitter without requiring us to actually\n * import the events definition (which is annoying with browsers).\n *\n * @internal\n */\ntype EventEmitterLike<T extends RheaPromiseReceiver | Session> = Pick<\n T,\n \"once\" | \"removeListener\" | \"on\"\n>;\n\n/**\n * The bare minimum needed to receive messages for batched\n * message receiving.\n *\n * @internal\n */\nexport type MinimalReceiver = Pick<\n RheaPromiseReceiver,\n \"name\" | \"isOpen\" | \"credit\" | \"addCredit\" | \"drain\" | \"drainCredit\" | \"close\"\n> &\n EventEmitterLike<RheaPromiseReceiver> & {\n session: EventEmitterLike<Session>;\n } & {\n connection: {\n id: string;\n };\n };\n\n/**\n * @internal\n */\ntype MessageAndDelivery = Pick<EventContext, \"message\" | \"delivery\">;\n\n/**\n * @internal\n */\ninterface ReceiveMessageArgs extends OperationOptionsBase {\n maxMessageCount: number;\n maxWaitTimeInMs: number;\n maxTimeAfterFirstMessageInMs: number;\n}\n\n/**\n * The internals of a batching receiver minus anything that would require us to hold onto a client entity context\n * or a receiver on a permanent basis.\n *\n * Usable with both session and non-session receivers.\n *\n * @internal\n */\nexport class BatchingReceiverLite {\n // testing hook\n private _drainTimeoutInMs: number = receiveDrainTimeoutInMs;\n constructor(\n private _connectionContext: ConnectionContext,\n public entityPath: string,\n private _getCurrentReceiver: (\n abortSignal?: AbortSignalLike,\n ) => Promise<MinimalReceiver | undefined>,\n private _receiveMode: ReceiveMode,\n _skipParsingBodyAsJson: boolean,\n _skipConvertingDate: boolean,\n ) {\n this._createServiceBusMessage = (context: MessageAndDelivery) => {\n return new ServiceBusMessageImpl(\n context.message!,\n context.delivery!,\n true,\n this._receiveMode,\n _skipParsingBodyAsJson,\n _skipConvertingDate,\n );\n };\n\n this._getRemainingWaitTimeInMsFn = (\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n ) => getRemainingWaitTimeInMsFn(maxWaitTimeInMs, maxTimeAfterFirstMessageInMs);\n\n this.isReceivingMessages = false;\n }\n\n private _createServiceBusMessage: (\n context: Pick<EventContext, \"message\" | \"delivery\">,\n ) => ServiceBusMessageImpl;\n\n private _getRemainingWaitTimeInMsFn: typeof getRemainingWaitTimeInMsFn;\n private _closeHandler: ((connectionError?: AmqpError | Error) => void) | undefined;\n private _finalAction: (() => void) | undefined;\n\n isReceivingMessages: boolean;\n\n /**\n * Receives a set of messages,\n *\n * @internal\n * @hidden\n */\n public async receiveMessages(args: ReceiveMessageArgs): Promise<ServiceBusMessageImpl[]> {\n try {\n this.isReceivingMessages = true;\n const receiver = await this._getCurrentReceiver(args.abortSignal);\n\n if (receiver == null) {\n // (was somehow closed in between the init() and the return)\n throw new ServiceBusError(\"Link closed before receiving messages.\", \"GeneralError\");\n }\n\n const messages = await new Promise<ServiceBusMessageImpl[]>((resolve, reject) =>\n this._receiveMessagesImpl(receiver, args, resolve, reject),\n );\n return tracingClient.withSpan(\n \"BatchingReceiverLite.process\",\n args,\n () => messages,\n toProcessingSpanOptions(messages, this, this._connectionContext.config, \"process\"),\n );\n } finally {\n this._closeHandler = undefined;\n this.isReceivingMessages = false;\n }\n }\n\n /**\n * Closes the receiver (optionally with an error), cancelling any current operations.\n *\n * @param connectionError - An optional error (rhea doesn't always deliver one for certain disconnection events)\n */\n terminate(connectionError?: Error | AmqpError): void {\n if (this._closeHandler) {\n this._closeHandler(connectionError);\n this._closeHandler = undefined;\n }\n }\n\n private async tryDrainReceiver(\n receiver: MinimalReceiver,\n loggingPrefix: string,\n remainingWaitTimeInMs: number,\n abortSignal?: AbortSignalLike,\n ): Promise<void> {\n if (!receiver.isOpen() || receiver.credit <= 0) {\n return;\n }\n let drainTimedout: boolean = false;\n let drainTimer: ReturnType<typeof setTimeout>;\n const timeToWaitInMs = Math.max(this._drainTimeoutInMs, remainingWaitTimeInMs);\n const drainPromise = new Promise<void>((resolve) => {\n function drainListener(): void {\n logger.verbose(`${loggingPrefix} Receiver has been drained.`);\n clearTimeout(drainTimer);\n resolve();\n }\n function removeListeners(): void {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n receiver.removeListener(ReceiverEvents.receiverDrained, drainListener);\n }\n function onAbort(): void {\n removeListeners();\n clearTimeout(drainTimer);\n resolve();\n }\n\n drainTimer = setTimeout(() => {\n drainTimedout = true;\n removeListeners();\n resolve();\n }, timeToWaitInMs);\n receiver.once(ReceiverEvents.receiverDrained, drainListener);\n abortSignal?.addEventListener(\"abort\", onAbort);\n });\n\n receiver.drainCredit();\n logger.verbose(\n `${loggingPrefix} Draining leftover credits(${receiver.credit}), waiting for event_drained event, or timing out after ${timeToWaitInMs} milliseconds...`,\n );\n await drainPromise;\n if (drainTimedout) {\n logger.warning(\n `${loggingPrefix} Time out after ${timeToWaitInMs} milliseconds when draining credits. Closing receiver...`,\n );\n // Close the receiver link since we have not received the receiver drain event\n // to prevent out-of-sync state between local and remote\n await receiver.close();\n }\n\n // Turn off draining.\n receiver.drain = false;\n }\n\n private _receiveMessagesImpl(\n receiver: MinimalReceiver,\n args: ReceiveMessageArgs,\n origResolve: (messages: ServiceBusMessageImpl[]) => void,\n origReject: (err: Error | AmqpError) => void,\n ): void {\n const getRemainingWaitTimeInMs = this._getRemainingWaitTimeInMsFn(\n args.maxWaitTimeInMs,\n args.maxTimeAfterFirstMessageInMs,\n );\n\n const brokeredMessages: ServiceBusMessageImpl[] = [];\n const loggingPrefix = `[${receiver.connection.id}|r:${receiver.name}]`;\n\n let totalWaitTimer: NodeJS.Timeout | undefined;\n // eslint-disable-next-line prefer-const\n let cleanupBeforeResolveOrReject: () => void;\n\n const rejectAfterCleanup = (err: Error | AmqpError): void => {\n cleanupBeforeResolveOrReject();\n origReject(err);\n };\n\n const resolveImmediately = (result: ServiceBusMessageImpl[]): void => {\n cleanupBeforeResolveOrReject();\n origResolve(result);\n };\n\n const resolveAfterPendingMessageCallbacks = (result: ServiceBusMessageImpl[]): void => {\n // NOTE: through rhea-promise, most of our event handlers are made asynchronous by calling setTimeout(emit).\n // However, a small set (*error and drain) execute immediately. This can lead to a situation where the logical\n // ordering of events is correct but the execution order is incorrect because the events are not all getting\n // put into the task queue the same way.\n // setTimeout() ensures that we resolve _after_ any already-queued onMessage handlers that may\n // be waiting in the task queue.\n setTimeout(() => {\n cleanupBeforeResolveOrReject();\n origResolve(result);\n });\n };\n\n const onError: OnAmqpEvent = (context: EventContext) => {\n const eventType = context.session?.error != null ? \"session_error\" : \"receiver_error\";\n let error = context.session?.error || context.receiver?.error;\n\n if (error) {\n error = translateServiceBusError(error);\n logger.logError(error, `${loggingPrefix} '${eventType}' event occurred. Received an error`);\n } else {\n error = new ServiceBusError(\"An error occurred while receiving messages.\", \"GeneralError\");\n }\n rejectAfterCleanup(error);\n };\n\n this._closeHandler = (error?: AmqpError | Error): void => {\n if (\n // no error, just closing. Go ahead and return what we have.\n error == null ||\n // Return the collected messages if in ReceiveAndDelete mode because otherwise they are lost forever\n (this._receiveMode === \"receiveAndDelete\" && brokeredMessages.length)\n ) {\n logger.verbose(\n `${loggingPrefix} Closing. Resolving with ${brokeredMessages.length} messages.`,\n );\n return resolveAfterPendingMessageCallbacks(brokeredMessages);\n }\n\n rejectAfterCleanup(translateServiceBusError(error));\n };\n\n let abortSignalCleanupFunction: (() => void) | undefined = undefined;\n\n // Final action to be performed after\n // - maxMessageCount is reached or\n // - maxWaitTime is passed or\n // - newMessageWaitTimeoutInSeconds is passed since the last message was received\n this._finalAction = async (): Promise<void> => {\n if (receiver.drain) {\n // If a drain is already in process then we should let it complete. Some messages might still be in flight, but they will\n // arrive before the drain completes.\n logger.verbose(`${loggingPrefix} Already draining.`);\n return;\n }\n\n const remainingWaitTimeInMs = getRemainingWaitTimeInMs();\n await this.tryDrainReceiver(receiver, loggingPrefix, remainingWaitTimeInMs, args.abortSignal);\n logger.verbose(\n `${loggingPrefix} Resolving receiveMessages() with ${brokeredMessages.length} messages.`,\n );\n resolveImmediately(brokeredMessages);\n };\n\n // Action to be performed on the \"message\" event.\n const onReceiveMessage: OnAmqpEventAsPromise = async (context: EventContext) => {\n // TODO: this appears to be aggravating a bug that we need to look into more deeply.\n // The same timeout+drain sequence should work fine for receiveAndDelete but it appears\n // to cause problems.\n if (this._receiveMode === \"peekLock\") {\n if (brokeredMessages.length === 0) {\n // We'll now remove the old timer (which was the overall `maxWaitTimeMs` timer)\n // and replace it with another timer that is a (probably) much shorter interval.\n //\n // This allows the user to get access to received messages earlier and also gives us\n // a chance to have fewer messages internally that could get lost if the user's\n // app crashes.\n if (totalWaitTimer) clearTimeout(totalWaitTimer);\n const remainingWaitTimeInMs = getRemainingWaitTimeInMs();\n totalWaitTimer = setTimeout(() => {\n logger.verbose(\n `${loggingPrefix} Batching, waited for ${remainingWaitTimeInMs} milliseconds after receiving the first message.`,\n );\n this._finalAction!();\n }, remainingWaitTimeInMs);\n }\n }\n\n try {\n const data: ServiceBusMessageImpl = this._createServiceBusMessage(context);\n brokeredMessages.push(data);\n\n // NOTE: we used to actually \"lose\" any extra messages. At this point I've fixed the areas that were causing us to receive\n // extra messages but if this bug arises in some other way it's better to return the message than it would be to let it be\n // silently dropped on the floor.\n if (brokeredMessages.length > args.maxMessageCount) {\n logger.warning(\n `More messages arrived than expected: ${args.maxMessageCount} vs ${brokeredMessages.length}`,\n );\n }\n } catch (err: any) {\n const errObj = err instanceof Error ? err : new Error(JSON.stringify(err));\n logger.logError(\n err,\n `${loggingPrefix} Received an error while converting AmqpMessage to ServiceBusMessage`,\n );\n rejectAfterCleanup(errObj);\n }\n if (brokeredMessages.length >= args.maxMessageCount) {\n this._finalAction!();\n }\n };\n\n const onClose: OnAmqpEventAsPromise = async (context: EventContext) => {\n const type = context.session?.error != null ? \"session_closed\" : \"receiver_closed\";\n const error = context.session?.error || context.receiver?.error;\n\n if (error) {\n logger.logError(error, `${loggingPrefix} '${type}' event occurred. The associated error`);\n }\n };\n\n cleanupBeforeResolveOrReject = (): void => {\n if (receiver != null) {\n receiver.removeListener(ReceiverEvents.receiverError, onError);\n receiver.removeListener(ReceiverEvents.message, onReceiveMessage);\n receiver.session.removeListener(SessionEvents.sessionError, onError);\n receiver.removeListener(ReceiverEvents.receiverClose, onClose);\n receiver.session.removeListener(SessionEvents.sessionClose, onClose);\n }\n\n if (totalWaitTimer) {\n clearTimeout(totalWaitTimer);\n }\n\n if (abortSignalCleanupFunction) {\n abortSignalCleanupFunction();\n }\n abortSignalCleanupFunction = undefined;\n };\n\n abortSignalCleanupFunction = checkAndRegisterWithAbortSignal((err) => {\n if (receiver.drain) {\n // If a drain is already in process and we cancel, the link state may be out of sync\n // with remote. Reset the link so that we will have fresh start.\n receiver.close();\n }\n rejectAfterCleanup(err);\n }, args.abortSignal);\n\n // By adding credit here, we let the service know that at max we can handle `maxMessageCount`\n // number of messages concurrently. We will return the user an array of messages that can\n // be of size upto maxMessageCount. Then the user needs to accordingly dispose\n // (complete/abandon/defer/deadletter) the messages from the array.\n const creditToAdd = args.maxMessageCount - receiver.credit;\n logger.verbose(\n `${loggingPrefix} Ensure enough credit for receiving ${args.maxMessageCount} messages. Current: ${receiver.credit}. To add: ${creditToAdd}.`,\n );\n\n if (creditToAdd > 0) {\n receiver.addCredit(creditToAdd);\n }\n\n logger.verbose(\n `${loggingPrefix} Setting the wait timer for ${args.maxWaitTimeInMs} milliseconds.`,\n );\n\n totalWaitTimer = setTimeout(() => {\n logger.verbose(\n `${loggingPrefix} Batching, waited for max wait time ${args.maxWaitTimeInMs} milliseconds.`,\n );\n this._finalAction!();\n }, args.maxWaitTimeInMs);\n\n receiver.on(ReceiverEvents.message, onReceiveMessage);\n receiver.on(ReceiverEvents.receiverError, onError);\n receiver.on(ReceiverEvents.receiverClose, onClose);\n\n receiver.session.on(SessionEvents.sessionError, onError);\n receiver.session.on(SessionEvents.sessionClose, onClose);\n }\n}\n"]}
1
+ {"version":3,"file":"batchingReceiver.js","sourceRoot":"","sources":["../../../src/core/batchingReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { receiverLogger as logger } from \"../log.js\";\nimport type {\n AmqpError,\n EventContext,\n OnAmqpEvent,\n Receiver as RheaPromiseReceiver,\n Session,\n} from \"rhea-promise\";\nimport { ReceiverEvents, SessionEvents } from \"rhea-promise\";\nimport { ServiceBusMessageImpl } from \"../serviceBusMessage.js\";\nimport type { OnAmqpEventAsPromise, ReceiveOptions } from \"./messageReceiver.js\";\nimport { MessageReceiver } from \"./messageReceiver.js\";\nimport type { ConnectionContext } from \"../connectionContext.js\";\nimport { throwErrorIfConnectionClosed } from \"../util/errors.js\";\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { checkAndRegisterWithAbortSignal } from \"../util/utils.js\";\nimport { receiveDrainTimeoutInMs } from \"../util/constants.js\";\nimport type { OperationOptionsBase } from \"../modelsToBeSharedWithEventHubs.js\";\nimport { toProcessingSpanOptions } from \"../diagnostics/instrumentServiceBusMessage.js\";\nimport type { ReceiveMode } from \"../models.js\";\nimport { ServiceBusError, translateServiceBusError } from \"../serviceBusError.js\";\nimport { tracingClient } from \"../diagnostics/tracing.js\";\n\n/**\n * Describes the batching receiver where the user can receive a specified number of messages for\n * a predefined time.\n * @internal\n */\nexport class BatchingReceiver extends MessageReceiver {\n /**\n * Instantiate a new BatchingReceiver.\n *\n * @param identifier - name to identify this receiver.\n * @param connectionContext - The client entity context.\n * @param options - Options for how you'd like to connect.\n */\n constructor(\n identifier: string,\n connectionContext: ConnectionContext,\n entityPath: string,\n options: ReceiveOptions,\n ) {\n super(identifier, connectionContext, entityPath, \"batching\", options);\n\n this._batchingReceiverLite = new BatchingReceiverLite(\n connectionContext,\n entityPath,\n async (abortSignal?: AbortSignalLike): Promise<MinimalReceiver | undefined> => {\n let lastError: Error | AmqpError | undefined;\n\n const rcvrOptions = this._createReceiverOptions(false, {\n onError: (context) => {\n lastError = context?.receiver?.error;\n },\n onSessionError: (context) => {\n lastError = context?.session?.error;\n },\n onClose: async () => {\n /** Nothing to do here - the next call will just fail so they'll get an appropriate error from somewhere else. */\n },\n onSessionClose: async () => {\n /** Nothing to do here - the next call will just fail so they'll get an appropriate error from somewhere else. */\n },\n onMessage: async () => {\n /** Nothing to do here - we don't add credits initially so we don't need to worry about handling any messages.*/\n },\n });\n\n await this._init(rcvrOptions, abortSignal);\n\n if (lastError != null) {\n throw lastError;\n }\n\n return this.link;\n },\n this.receiveMode,\n options.skipParsingBodyAsJson ?? false,\n options.skipConvertingDate ?? false,\n );\n }\n\n private _batchingReceiverLite: BatchingReceiverLite;\n\n get isReceivingMessages(): boolean {\n return this._batchingReceiverLite.isReceivingMessages;\n }\n\n /**\n * To be called when connection is disconnected to gracefully close ongoing receive request.\n * @param connectionError - The connection error if any.\n */\n async onDetached(connectionError?: AmqpError | Error): Promise<void> {\n await this.closeLink();\n\n if (connectionError == null) {\n connectionError = new Error(\n \"Unknown error occurred on the AMQP connection while receiving messages.\",\n );\n }\n\n this._batchingReceiverLite.terminate(connectionError);\n }\n\n /**\n * Receives a batch of messages from a ServiceBus Queue/Topic.\n * @param maxMessageCount - The maximum number of messages to receive.\n * In Peeklock mode, this number is capped at 2047 due to constraints of the underlying buffer.\n * @param maxWaitTimeInMs - The total wait time in milliseconds until which the receiver will attempt to receive specified number of messages.\n * @param maxTimeAfterFirstMessageInMs - The total amount of time to wait after the first message\n * has been received. Defaults to 1 second.\n * If this time elapses before the `maxMessageCount` is reached, then messages collected till then will be returned to the user.\n * @returns A promise that resolves with an array of Message objects.\n */\n async receive(\n maxMessageCount: number,\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n options: OperationOptionsBase,\n ): Promise<ServiceBusMessageImpl[]> {\n throwErrorIfConnectionClosed(this._context);\n try {\n const messages = await this._batchingReceiverLite.receiveMessages({\n maxMessageCount,\n maxWaitTimeInMs,\n maxTimeAfterFirstMessageInMs,\n ...options,\n });\n\n if (this._lockRenewer) {\n for (const message of messages) {\n this._lockRenewer.start(this, message, (_error) => {\n // the auto lock renewer already logs this in a detailed way. So this hook is mainly here\n // to potentially forward the error to the user (which we're not doing yet)\n });\n }\n }\n\n return messages;\n } catch (error: any) {\n logger.logError(error, \"[%s] Rejecting receiveMessages()\", this.logPrefix);\n throw error;\n }\n }\n\n static create(\n clientId: string,\n context: ConnectionContext,\n entityPath: string,\n options: ReceiveOptions,\n ): BatchingReceiver {\n throwErrorIfConnectionClosed(context);\n const bReceiver = new BatchingReceiver(clientId, context, entityPath, options);\n context.messageReceivers[bReceiver.name] = bReceiver;\n return bReceiver;\n }\n\n protected removeLinkFromContext(): void {\n delete this._context.messageReceivers[this.name];\n }\n}\n\n/**\n * Gets a function that returns the smaller of the two timeouts,\n * taking into account elapsed time from when getRemainingWaitTimeInMsFn\n * was called.\n *\n * @param maxWaitTimeInMs - Maximum time to wait for the first message\n * @param maxTimeAfterFirstMessageInMs - Maximum time to wait after the first message before completing the receive.\n *\n * @internal\n */\nexport function getRemainingWaitTimeInMsFn(\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n): () => number {\n const startTimeMs = Date.now();\n\n return () => {\n const remainingTimeMs = maxWaitTimeInMs - (Date.now() - startTimeMs);\n\n if (remainingTimeMs < 0) {\n return 0;\n }\n\n return Math.min(remainingTimeMs, maxTimeAfterFirstMessageInMs);\n };\n}\n\n/**\n * Useful interface that mimics EventEmitter without requiring us to actually\n * import the events definition (which is annoying with browsers).\n *\n * @internal\n */\ntype EventEmitterLike<T extends RheaPromiseReceiver | Session> = Pick<\n T,\n \"once\" | \"removeListener\" | \"on\"\n>;\n\n/**\n * The bare minimum needed to receive messages for batched\n * message receiving.\n *\n * @internal\n */\nexport type MinimalReceiver = Pick<\n RheaPromiseReceiver,\n \"name\" | \"isOpen\" | \"credit\" | \"addCredit\" | \"drain\" | \"drainCredit\" | \"close\"\n> &\n EventEmitterLike<RheaPromiseReceiver> & {\n session: EventEmitterLike<Session>;\n } & {\n connection: {\n id: string;\n };\n };\n\n/**\n * @internal\n */\ntype MessageAndDelivery = Pick<EventContext, \"message\" | \"delivery\">;\n\n/**\n * @internal\n */\ninterface ReceiveMessageArgs extends OperationOptionsBase {\n maxMessageCount: number;\n maxWaitTimeInMs: number;\n maxTimeAfterFirstMessageInMs: number;\n}\n\n/**\n * The internals of a batching receiver minus anything that would require us to hold onto a client entity context\n * or a receiver on a permanent basis.\n *\n * Usable with both session and non-session receivers.\n *\n * @internal\n */\nexport class BatchingReceiverLite {\n // testing hook\n private _drainTimeoutInMs: number = receiveDrainTimeoutInMs;\n constructor(\n private _connectionContext: ConnectionContext,\n public entityPath: string,\n private _getCurrentReceiver: (\n abortSignal?: AbortSignalLike,\n ) => Promise<MinimalReceiver | undefined>,\n private _receiveMode: ReceiveMode,\n _skipParsingBodyAsJson: boolean,\n _skipConvertingDate: boolean,\n ) {\n this._createServiceBusMessage = (context: MessageAndDelivery) => {\n return new ServiceBusMessageImpl(\n context.message!,\n context.delivery!,\n true,\n this._receiveMode,\n _skipParsingBodyAsJson,\n _skipConvertingDate,\n );\n };\n\n this._getRemainingWaitTimeInMsFn = (\n maxWaitTimeInMs: number,\n maxTimeAfterFirstMessageInMs: number,\n ) => getRemainingWaitTimeInMsFn(maxWaitTimeInMs, maxTimeAfterFirstMessageInMs);\n\n this.isReceivingMessages = false;\n }\n\n private _createServiceBusMessage: (\n context: Pick<EventContext, \"message\" | \"delivery\">,\n ) => ServiceBusMessageImpl;\n\n private _getRemainingWaitTimeInMsFn: typeof getRemainingWaitTimeInMsFn;\n private _closeHandler: ((connectionError?: AmqpError | Error) => void) | undefined;\n private _finalAction: (() => void) | undefined;\n\n isReceivingMessages: boolean;\n\n /**\n * Receives a set of messages,\n *\n * @internal\n * @hidden\n */\n public async receiveMessages(args: ReceiveMessageArgs): Promise<ServiceBusMessageImpl[]> {\n try {\n this.isReceivingMessages = true;\n const receiver = await this._getCurrentReceiver(args.abortSignal);\n\n if (receiver == null) {\n // (was somehow closed in between the init() and the return)\n throw new ServiceBusError(\"Link closed before receiving messages.\", \"GeneralError\");\n }\n\n const messages = await new Promise<ServiceBusMessageImpl[]>((resolve, reject) =>\n this._receiveMessagesImpl(receiver, args, resolve, reject),\n );\n return tracingClient.withSpan(\n \"BatchingReceiverLite.process\",\n args,\n () => messages,\n toProcessingSpanOptions(messages, this, this._connectionContext.config, \"process\"),\n );\n } finally {\n this._closeHandler = undefined;\n this.isReceivingMessages = false;\n }\n }\n\n /**\n * Closes the receiver (optionally with an error), cancelling any current operations.\n *\n * @param connectionError - An optional error (rhea doesn't always deliver one for certain disconnection events)\n */\n terminate(connectionError?: Error | AmqpError): void {\n if (this._closeHandler) {\n this._closeHandler(connectionError);\n this._closeHandler = undefined;\n }\n }\n\n private async tryDrainReceiver(\n receiver: MinimalReceiver,\n loggingPrefix: string,\n remainingWaitTimeInMs: number,\n abortSignal?: AbortSignalLike,\n ): Promise<void> {\n if (!receiver.isOpen() || receiver.credit <= 0) {\n return;\n }\n let drainTimedout: boolean = false;\n let drainTimer: ReturnType<typeof setTimeout>;\n const timeToWaitInMs = Math.max(this._drainTimeoutInMs, remainingWaitTimeInMs);\n const drainPromise = new Promise<void>((resolve) => {\n function drainListener(): void {\n logger.verbose(`${loggingPrefix} Receiver has been drained.`);\n clearTimeout(drainTimer);\n resolve();\n }\n function removeListeners(): void {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n receiver.removeListener(ReceiverEvents.receiverDrained, drainListener);\n }\n function onAbort(): void {\n removeListeners();\n clearTimeout(drainTimer);\n resolve();\n }\n\n drainTimer = setTimeout(() => {\n drainTimedout = true;\n removeListeners();\n resolve();\n }, timeToWaitInMs);\n receiver.once(ReceiverEvents.receiverDrained, drainListener);\n abortSignal?.addEventListener(\"abort\", onAbort);\n });\n\n receiver.drainCredit();\n logger.verbose(\n `${loggingPrefix} Draining leftover credits(${receiver.credit}), waiting for event_drained event, or timing out after ${timeToWaitInMs} milliseconds...`,\n );\n await drainPromise;\n if (drainTimedout) {\n logger.warning(\n `${loggingPrefix} Time out after ${timeToWaitInMs} milliseconds when draining credits. Closing receiver...`,\n );\n // Close the receiver link since we have not received the receiver drain event\n // to prevent out-of-sync state between local and remote\n await receiver.close();\n }\n\n // Turn off draining.\n receiver.drain = false;\n }\n\n private _receiveMessagesImpl(\n receiver: MinimalReceiver,\n args: ReceiveMessageArgs,\n origResolve: (messages: ServiceBusMessageImpl[]) => void,\n origReject: (err: Error | AmqpError) => void,\n ): void {\n const getRemainingWaitTimeInMs = this._getRemainingWaitTimeInMsFn(\n args.maxWaitTimeInMs,\n args.maxTimeAfterFirstMessageInMs,\n );\n\n const brokeredMessages: ServiceBusMessageImpl[] = [];\n const loggingPrefix = `[${receiver.connection.id}|r:${receiver.name}]`;\n\n let totalWaitTimer: NodeJS.Timeout | undefined;\n // eslint-disable-next-line prefer-const\n let cleanupBeforeResolveOrReject: () => void;\n\n const rejectAfterCleanup = (err: Error | AmqpError): void => {\n cleanupBeforeResolveOrReject();\n origReject(err);\n };\n\n const resolveImmediately = (result: ServiceBusMessageImpl[]): void => {\n cleanupBeforeResolveOrReject();\n origResolve(result);\n };\n\n const resolveAfterPendingMessageCallbacks = (result: ServiceBusMessageImpl[]): void => {\n // NOTE: through rhea-promise, most of our event handlers are made asynchronous by calling setTimeout(emit).\n // However, a small set (*error and drain) execute immediately. This can lead to a situation where the logical\n // ordering of events is correct but the execution order is incorrect because the events are not all getting\n // put into the task queue the same way.\n // setTimeout() ensures that we resolve _after_ any already-queued onMessage handlers that may\n // be waiting in the task queue.\n setTimeout(() => {\n cleanupBeforeResolveOrReject();\n origResolve(result);\n });\n };\n\n const onError: OnAmqpEvent = (context: EventContext) => {\n const eventType = context.session?.error != null ? \"session_error\" : \"receiver_error\";\n let error = context.session?.error || context.receiver?.error;\n\n if (error) {\n error = translateServiceBusError(error);\n logger.logError(error, `${loggingPrefix} '${eventType}' event occurred. Received an error`);\n } else {\n error = new ServiceBusError(\"An error occurred while receiving messages.\", \"GeneralError\");\n }\n rejectAfterCleanup(error);\n };\n\n this._closeHandler = (error?: AmqpError | Error): void => {\n if (\n // no error, just closing. Go ahead and return what we have.\n error == null ||\n // Return the collected messages if in ReceiveAndDelete mode because otherwise they are lost forever\n (this._receiveMode === \"receiveAndDelete\" && brokeredMessages.length)\n ) {\n logger.verbose(\n `${loggingPrefix} Closing. Resolving with ${brokeredMessages.length} messages.`,\n );\n return resolveAfterPendingMessageCallbacks(brokeredMessages);\n }\n\n rejectAfterCleanup(translateServiceBusError(error));\n };\n\n let abortSignalCleanupFunction: (() => void) | undefined = undefined;\n\n // Final action to be performed after\n // - maxMessageCount is reached or\n // - maxWaitTime is passed or\n // - newMessageWaitTimeoutInSeconds is passed since the last message was received\n this._finalAction = async (): Promise<void> => {\n if (receiver.drain) {\n // If a drain is already in process then we should let it complete. Some messages might still be in flight, but they will\n // arrive before the drain completes.\n logger.verbose(`${loggingPrefix} Already draining.`);\n return;\n }\n\n const remainingWaitTimeInMs = getRemainingWaitTimeInMs();\n await this.tryDrainReceiver(receiver, loggingPrefix, remainingWaitTimeInMs, args.abortSignal);\n logger.verbose(\n `${loggingPrefix} Resolving receiveMessages() with ${brokeredMessages.length} messages.`,\n );\n resolveImmediately(brokeredMessages);\n };\n\n // Action to be performed on the \"message\" event.\n const onReceiveMessage: OnAmqpEventAsPromise = async (context: EventContext) => {\n // TODO: this appears to be aggravating a bug that we need to look into more deeply.\n // The same timeout+drain sequence should work fine for receiveAndDelete but it appears\n // to cause problems.\n if (this._receiveMode === \"peekLock\") {\n if (brokeredMessages.length === 0) {\n // We'll now remove the old timer (which was the overall `maxWaitTimeMs` timer)\n // and replace it with another timer that is a (probably) much shorter interval.\n //\n // This allows the user to get access to received messages earlier and also gives us\n // a chance to have fewer messages internally that could get lost if the user's\n // app crashes.\n if (totalWaitTimer) clearTimeout(totalWaitTimer);\n const remainingWaitTimeInMs = getRemainingWaitTimeInMs();\n totalWaitTimer = setTimeout(() => {\n logger.verbose(\n `${loggingPrefix} Batching, waited for ${remainingWaitTimeInMs} milliseconds after receiving the first message.`,\n );\n this._finalAction!();\n }, remainingWaitTimeInMs);\n }\n }\n\n try {\n const data: ServiceBusMessageImpl = this._createServiceBusMessage(context);\n brokeredMessages.push(data);\n\n // NOTE: we used to actually \"lose\" any extra messages. At this point I've fixed the areas that were causing us to receive\n // extra messages but if this bug arises in some other way it's better to return the message than it would be to let it be\n // silently dropped on the floor.\n if (brokeredMessages.length > args.maxMessageCount) {\n logger.warning(\n `More messages arrived than expected: ${args.maxMessageCount} vs ${brokeredMessages.length}`,\n );\n }\n } catch (err: any) {\n const errObj = err instanceof Error ? err : new Error(JSON.stringify(err));\n logger.logError(\n err,\n `${loggingPrefix} Received an error while converting AmqpMessage to ServiceBusMessage`,\n );\n rejectAfterCleanup(errObj);\n }\n if (brokeredMessages.length >= args.maxMessageCount) {\n this._finalAction!();\n }\n };\n\n const onClose: OnAmqpEventAsPromise = async (context: EventContext) => {\n const type = context.session?.error != null ? \"session_closed\" : \"receiver_closed\";\n const error = context.session?.error || context.receiver?.error;\n\n if (error) {\n logger.logError(error, `${loggingPrefix} '${type}' event occurred. The associated error`);\n }\n };\n\n cleanupBeforeResolveOrReject = (): void => {\n if (receiver != null) {\n receiver.removeListener(ReceiverEvents.receiverError, onError);\n receiver.removeListener(ReceiverEvents.message, onReceiveMessage);\n receiver.session.removeListener(SessionEvents.sessionError, onError);\n receiver.removeListener(ReceiverEvents.receiverClose, onClose);\n receiver.session.removeListener(SessionEvents.sessionClose, onClose);\n }\n\n if (totalWaitTimer) {\n clearTimeout(totalWaitTimer);\n }\n\n if (abortSignalCleanupFunction) {\n abortSignalCleanupFunction();\n }\n abortSignalCleanupFunction = undefined;\n };\n\n abortSignalCleanupFunction = checkAndRegisterWithAbortSignal((err) => {\n if (receiver.drain) {\n // If a drain is already in process and we cancel, the link state may be out of sync\n // with remote. Reset the link so that we will have fresh start.\n receiver.close();\n }\n rejectAfterCleanup(err);\n }, args.abortSignal);\n\n // By adding credit here, we let the service know that at max we can handle `maxMessageCount`\n // number of messages concurrently. We will return the user an array of messages that can\n // be of size upto maxMessageCount. Then the user needs to accordingly dispose\n // (complete/abandon/defer/deadletter) the messages from the array.\n const creditToAdd = args.maxMessageCount - receiver.credit;\n logger.verbose(\n `${loggingPrefix} Ensure enough credit for receiving ${args.maxMessageCount} messages. Current: ${receiver.credit}. To add: ${creditToAdd}.`,\n );\n\n if (creditToAdd > 0) {\n receiver.addCredit(creditToAdd);\n }\n\n logger.verbose(\n `${loggingPrefix} Setting the wait timer for ${args.maxWaitTimeInMs} milliseconds.`,\n );\n\n totalWaitTimer = setTimeout(() => {\n logger.verbose(\n `${loggingPrefix} Batching, waited for max wait time ${args.maxWaitTimeInMs} milliseconds.`,\n );\n this._finalAction!();\n }, args.maxWaitTimeInMs);\n\n receiver.on(ReceiverEvents.message, onReceiveMessage);\n receiver.on(ReceiverEvents.receiverError, onError);\n receiver.on(ReceiverEvents.receiverClose, onClose);\n\n receiver.session.on(SessionEvents.sessionError, onError);\n receiver.session.on(SessionEvents.sessionClose, onClose);\n }\n}\n"]}
@@ -10,9 +10,81 @@ import { ServiceBusError } from "../serviceBusError.js";
10
10
  * Describes the base class for entities like MessageSender, MessageReceiver and Management client.
11
11
  */
12
12
  export class LinkEntity {
13
+ baseName;
14
+ entityPath;
15
+ _linkType;
16
+ _logger;
17
+ /**
18
+ * The unique name for the entity in the format:
19
+ * `${name of the entity}-${guid}`.
20
+ */
21
+ name;
22
+ /**
23
+ * The client entity address in one of the following forms:
24
+ *
25
+ * **Sender**
26
+ * - `"<queue-name>"`.
27
+ * - `"<topic-name>"`.
28
+ *
29
+ * **Receiver**
30
+ * - `"<queue-name>"`.
31
+ * - `"<topic-name>"`.
32
+ *
33
+ * **ManagementClient**
34
+ * -`"$management"`.
35
+ */
36
+ address;
37
+ /**
38
+ * The client entity token audience in one of the following forms:
39
+ *
40
+ * **Sender**
41
+ * - `"sb://<yournamespace>.servicebus.windows.net/<queue-name>"`
42
+ * - `"sb://<yournamespace>.servicebus.windows.net/<topic-name>"`
43
+ *
44
+ * **Receiver**
45
+ * - `"sb://<yournamespace>.servicebus.windows.net/<queue-name>"`
46
+ * - `"sb://<yournamespace>.servicebus.windows.net/<topic-name>"`
47
+ *
48
+ * **ManagementClient**
49
+ * - `"sb://<your-namespace>.servicebus.windows.net/<queue-name>/$management"`.
50
+ * - `"sb://<your-namespace>.servicebus.windows.net/<topic-name>/$management"`.
51
+ */
52
+ audience;
53
+ /**
54
+ * Provides relevant information about the amqp connection,
55
+ * cbs and $management sessions, token provider, sender and receivers.
56
+ */
57
+ _context;
58
+ /**
59
+ * The token renewal timer that keeps track of when
60
+ * the Client Entity is due for token renewal.
61
+ */
62
+ _tokenRenewalTimer;
63
+ /**
64
+ * Indicates token timeout
65
+ */
66
+ _tokenTimeout;
67
+ /**
68
+ * The actual rhea link (of type Receiver or AwaitableSender) or RequestResponseLink
69
+ */
70
+ _link;
71
+ /**
72
+ * The log prefix for any log messages.
73
+ */
74
+ _logPrefix;
13
75
  get logPrefix() {
14
76
  return this._logPrefix;
15
77
  }
78
+ /**
79
+ * Indicates that close() has been called on this link and
80
+ * that it should not be allowed to reopen.
81
+ */
82
+ _wasClosedPermanently = false;
83
+ /**
84
+ * A lock that ensures that opening and closing this
85
+ * link properly cooperate.
86
+ */
87
+ _openLock = `linkEntity-${generate_uuid()}`;
16
88
  /**
17
89
  * Creates a new ClientEntity instance.
18
90
  * @param baseName - The base name to use for the link. A unique ID will be appended to this.
@@ -25,16 +97,6 @@ export class LinkEntity {
25
97
  this.entityPath = entityPath;
26
98
  this._linkType = _linkType;
27
99
  this._logger = _logger;
28
- /**
29
- * Indicates that close() has been called on this link and
30
- * that it should not be allowed to reopen.
31
- */
32
- this._wasClosedPermanently = false;
33
- /**
34
- * A lock that ensures that opening and closing this
35
- * link properly cooperate.
36
- */
37
- this._openLock = `linkEntity-${generate_uuid()}`;
38
100
  if (!options)
39
101
  options = {};
40
102
  this._context = context;
@@ -72,9 +134,8 @@ export class LinkEntity {
72
134
  }
73
135
  async _initLinkImpl(options, abortSignal) {
74
136
  const checkAborted = () => {
75
- var _a;
76
- if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
77
- (_a = this._link) === null || _a === void 0 ? void 0 : _a.close();
137
+ if (abortSignal?.aborted) {
138
+ this._link?.close();
78
139
  throw new AbortError(StandardAbortMessage);
79
140
  }
80
141
  };