@azure/cosmos 4.5.1 → 4.6.0

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 (323) hide show
  1. package/README.md +32 -0
  2. package/dist/browser/ClientContext.d.ts.map +1 -1
  3. package/dist/browser/ClientContext.js +110 -19
  4. package/dist/browser/ClientContext.js.map +1 -1
  5. package/dist/browser/CosmosClient.d.ts +13 -0
  6. package/dist/browser/CosmosClient.d.ts.map +1 -1
  7. package/dist/browser/CosmosClient.js +19 -3
  8. package/dist/browser/CosmosClient.js.map +1 -1
  9. package/dist/browser/CosmosClientOptions.d.ts.map +1 -1
  10. package/dist/browser/CosmosClientOptions.js.map +1 -1
  11. package/dist/browser/CosmosDiagnostics.d.ts +4 -0
  12. package/dist/browser/CosmosDiagnostics.d.ts.map +1 -1
  13. package/dist/browser/CosmosDiagnostics.js.map +1 -1
  14. package/dist/browser/GlobalEndpointManagerOptions.d.ts +2 -0
  15. package/dist/browser/GlobalEndpointManagerOptions.d.ts.map +1 -0
  16. package/dist/browser/GlobalEndpointManagerOptions.js +2 -0
  17. package/dist/browser/GlobalEndpointManagerOptions.js.map +1 -0
  18. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  19. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  20. package/dist/browser/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  21. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  22. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  23. package/dist/browser/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  24. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  25. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  26. package/dist/browser/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  27. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  28. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  29. package/dist/browser/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  30. package/dist/browser/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  31. package/dist/browser/client/ChangeFeed/changeFeedUtils.js +1 -0
  32. package/dist/browser/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  33. package/dist/browser/client/Item/Items.d.ts.map +1 -1
  34. package/dist/browser/client/Item/Items.js +5 -0
  35. package/dist/browser/client/Item/Items.js.map +1 -1
  36. package/dist/browser/common/constants.d.ts +4 -0
  37. package/dist/browser/common/constants.d.ts.map +1 -1
  38. package/dist/browser/common/constants.js +5 -1
  39. package/dist/browser/common/constants.js.map +1 -1
  40. package/dist/browser/common/helper.d.ts +6 -0
  41. package/dist/browser/common/helper.d.ts.map +1 -1
  42. package/dist/browser/common/helper.js +9 -1
  43. package/dist/browser/common/helper.js.map +1 -1
  44. package/dist/browser/common/platform.d.ts +1 -0
  45. package/dist/browser/common/platform.d.ts.map +1 -1
  46. package/dist/browser/common/platform.js +1 -3
  47. package/dist/browser/common/platform.js.map +1 -1
  48. package/dist/browser/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  49. package/dist/browser/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  50. package/dist/browser/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  51. package/dist/browser/documents/ConnectionPolicy.d.ts +10 -4
  52. package/dist/browser/documents/ConnectionPolicy.d.ts.map +1 -1
  53. package/dist/browser/documents/ConnectionPolicy.js +2 -2
  54. package/dist/browser/documents/ConnectionPolicy.js.map +1 -1
  55. package/dist/browser/documents/DatabaseAccount.d.ts +4 -0
  56. package/dist/browser/documents/DatabaseAccount.d.ts.map +1 -1
  57. package/dist/browser/documents/DatabaseAccount.js +9 -0
  58. package/dist/browser/documents/DatabaseAccount.js.map +1 -1
  59. package/dist/browser/globalEndpointManager.d.ts +8 -0
  60. package/dist/browser/globalEndpointManager.d.ts.map +1 -1
  61. package/dist/browser/globalEndpointManager.js +68 -6
  62. package/dist/browser/globalEndpointManager.js.map +1 -1
  63. package/dist/browser/globalPartitionEndpointManager.d.ts +0 -2
  64. package/dist/browser/globalPartitionEndpointManager.d.ts.map +1 -1
  65. package/dist/browser/globalPartitionEndpointManager.js +13 -9
  66. package/dist/browser/globalPartitionEndpointManager.js.map +1 -1
  67. package/dist/browser/request/RequestHandler.js +2 -2
  68. package/dist/browser/request/RequestHandler.js.map +1 -1
  69. package/dist/browser/request/SharedOptions.d.ts +5 -0
  70. package/dist/browser/request/SharedOptions.d.ts.map +1 -1
  71. package/dist/browser/request/SharedOptions.js.map +1 -1
  72. package/dist/browser/retry/retryUtility.d.ts.map +1 -1
  73. package/dist/browser/retry/retryUtility.js +17 -3
  74. package/dist/browser/retry/retryUtility.js.map +1 -1
  75. package/dist/browser/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  76. package/dist/browser/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  77. package/dist/browser/retry/timeoutFailoverRetryPolicy.js +4 -4
  78. package/dist/browser/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  79. package/dist/browser/utils/encode.d.ts +1 -1
  80. package/dist/browser/utils/encode.d.ts.map +1 -1
  81. package/dist/browser/utils/encode.js.map +1 -1
  82. package/dist/commonjs/ClientContext.d.ts.map +1 -1
  83. package/dist/commonjs/ClientContext.js +110 -19
  84. package/dist/commonjs/ClientContext.js.map +1 -1
  85. package/dist/commonjs/CosmosClient.d.ts +13 -0
  86. package/dist/commonjs/CosmosClient.d.ts.map +1 -1
  87. package/dist/commonjs/CosmosClient.js +19 -3
  88. package/dist/commonjs/CosmosClient.js.map +1 -1
  89. package/dist/commonjs/CosmosClientOptions.d.ts.map +1 -1
  90. package/dist/commonjs/CosmosClientOptions.js.map +1 -1
  91. package/dist/commonjs/CosmosDiagnostics.d.ts +4 -0
  92. package/dist/commonjs/CosmosDiagnostics.d.ts.map +1 -1
  93. package/dist/commonjs/CosmosDiagnostics.js.map +1 -1
  94. package/dist/commonjs/GlobalEndpointManagerOptions.d.ts +2 -0
  95. package/dist/commonjs/GlobalEndpointManagerOptions.d.ts.map +1 -0
  96. package/dist/commonjs/GlobalEndpointManagerOptions.js +3 -0
  97. package/dist/commonjs/GlobalEndpointManagerOptions.js.map +1 -0
  98. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  99. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  100. package/dist/commonjs/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  101. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  102. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  103. package/dist/commonjs/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  104. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  105. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  106. package/dist/commonjs/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  107. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  108. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  109. package/dist/commonjs/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  110. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  111. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.js +1 -0
  112. package/dist/commonjs/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  113. package/dist/commonjs/client/Item/Items.d.ts.map +1 -1
  114. package/dist/commonjs/client/Item/Items.js +5 -0
  115. package/dist/commonjs/client/Item/Items.js.map +1 -1
  116. package/dist/commonjs/common/constants.d.ts +4 -0
  117. package/dist/commonjs/common/constants.d.ts.map +1 -1
  118. package/dist/commonjs/common/constants.js +6 -2
  119. package/dist/commonjs/common/constants.js.map +1 -1
  120. package/dist/commonjs/common/helper.d.ts +6 -0
  121. package/dist/commonjs/common/helper.d.ts.map +1 -1
  122. package/dist/commonjs/common/helper.js +9 -0
  123. package/dist/commonjs/common/helper.js.map +1 -1
  124. package/dist/commonjs/common/platform.d.ts +1 -0
  125. package/dist/commonjs/common/platform.d.ts.map +1 -1
  126. package/dist/commonjs/common/platform.js +1 -3
  127. package/dist/commonjs/common/platform.js.map +1 -1
  128. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  129. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  130. package/dist/commonjs/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  131. package/dist/commonjs/documents/ConnectionPolicy.d.ts +10 -4
  132. package/dist/commonjs/documents/ConnectionPolicy.d.ts.map +1 -1
  133. package/dist/commonjs/documents/ConnectionPolicy.js +2 -2
  134. package/dist/commonjs/documents/ConnectionPolicy.js.map +1 -1
  135. package/dist/commonjs/documents/DatabaseAccount.d.ts +4 -0
  136. package/dist/commonjs/documents/DatabaseAccount.d.ts.map +1 -1
  137. package/dist/commonjs/documents/DatabaseAccount.js +9 -0
  138. package/dist/commonjs/documents/DatabaseAccount.js.map +1 -1
  139. package/dist/commonjs/globalEndpointManager.d.ts +8 -0
  140. package/dist/commonjs/globalEndpointManager.d.ts.map +1 -1
  141. package/dist/commonjs/globalEndpointManager.js +68 -6
  142. package/dist/commonjs/globalEndpointManager.js.map +1 -1
  143. package/dist/commonjs/globalPartitionEndpointManager.d.ts +0 -2
  144. package/dist/commonjs/globalPartitionEndpointManager.d.ts.map +1 -1
  145. package/dist/commonjs/globalPartitionEndpointManager.js +13 -9
  146. package/dist/commonjs/globalPartitionEndpointManager.js.map +1 -1
  147. package/dist/commonjs/request/RequestHandler.js +2 -2
  148. package/dist/commonjs/request/RequestHandler.js.map +1 -1
  149. package/dist/commonjs/request/SharedOptions.d.ts +5 -0
  150. package/dist/commonjs/request/SharedOptions.d.ts.map +1 -1
  151. package/dist/commonjs/request/SharedOptions.js.map +1 -1
  152. package/dist/commonjs/retry/retryUtility.d.ts.map +1 -1
  153. package/dist/commonjs/retry/retryUtility.js +17 -3
  154. package/dist/commonjs/retry/retryUtility.js.map +1 -1
  155. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  156. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  157. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.js +4 -4
  158. package/dist/commonjs/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  159. package/dist/commonjs/tsdoc-metadata.json +1 -1
  160. package/dist/commonjs/utils/encode.d.ts +1 -1
  161. package/dist/commonjs/utils/encode.d.ts.map +1 -1
  162. package/dist/commonjs/utils/encode.js.map +1 -1
  163. package/dist/esm/ClientContext.d.ts.map +1 -1
  164. package/dist/esm/ClientContext.js +110 -19
  165. package/dist/esm/ClientContext.js.map +1 -1
  166. package/dist/esm/CosmosClient.d.ts +13 -0
  167. package/dist/esm/CosmosClient.d.ts.map +1 -1
  168. package/dist/esm/CosmosClient.js +19 -3
  169. package/dist/esm/CosmosClient.js.map +1 -1
  170. package/dist/esm/CosmosClientOptions.d.ts.map +1 -1
  171. package/dist/esm/CosmosClientOptions.js.map +1 -1
  172. package/dist/esm/CosmosDiagnostics.d.ts +4 -0
  173. package/dist/esm/CosmosDiagnostics.d.ts.map +1 -1
  174. package/dist/esm/CosmosDiagnostics.js.map +1 -1
  175. package/dist/esm/GlobalEndpointManagerOptions.d.ts +2 -0
  176. package/dist/esm/GlobalEndpointManagerOptions.d.ts.map +1 -0
  177. package/dist/esm/GlobalEndpointManagerOptions.js +2 -0
  178. package/dist/esm/GlobalEndpointManagerOptions.js.map +1 -0
  179. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  180. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  181. package/dist/esm/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  182. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  183. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  184. package/dist/esm/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  185. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  186. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  187. package/dist/esm/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  188. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  189. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  190. package/dist/esm/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  191. package/dist/esm/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  192. package/dist/esm/client/ChangeFeed/changeFeedUtils.js +1 -0
  193. package/dist/esm/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  194. package/dist/esm/client/Item/Items.d.ts.map +1 -1
  195. package/dist/esm/client/Item/Items.js +5 -0
  196. package/dist/esm/client/Item/Items.js.map +1 -1
  197. package/dist/esm/common/constants.d.ts +4 -0
  198. package/dist/esm/common/constants.d.ts.map +1 -1
  199. package/dist/esm/common/constants.js +5 -1
  200. package/dist/esm/common/constants.js.map +1 -1
  201. package/dist/esm/common/helper.d.ts +6 -0
  202. package/dist/esm/common/helper.d.ts.map +1 -1
  203. package/dist/esm/common/helper.js +9 -1
  204. package/dist/esm/common/helper.js.map +1 -1
  205. package/dist/esm/common/platform.d.ts +1 -0
  206. package/dist/esm/common/platform.d.ts.map +1 -1
  207. package/dist/esm/common/platform.js +1 -3
  208. package/dist/esm/common/platform.js.map +1 -1
  209. package/dist/esm/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  210. package/dist/esm/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  211. package/dist/esm/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  212. package/dist/esm/documents/ConnectionPolicy.d.ts +10 -4
  213. package/dist/esm/documents/ConnectionPolicy.d.ts.map +1 -1
  214. package/dist/esm/documents/ConnectionPolicy.js +2 -2
  215. package/dist/esm/documents/ConnectionPolicy.js.map +1 -1
  216. package/dist/esm/documents/DatabaseAccount.d.ts +4 -0
  217. package/dist/esm/documents/DatabaseAccount.d.ts.map +1 -1
  218. package/dist/esm/documents/DatabaseAccount.js +9 -0
  219. package/dist/esm/documents/DatabaseAccount.js.map +1 -1
  220. package/dist/esm/globalEndpointManager.d.ts +8 -0
  221. package/dist/esm/globalEndpointManager.d.ts.map +1 -1
  222. package/dist/esm/globalEndpointManager.js +68 -6
  223. package/dist/esm/globalEndpointManager.js.map +1 -1
  224. package/dist/esm/globalPartitionEndpointManager.d.ts +0 -2
  225. package/dist/esm/globalPartitionEndpointManager.d.ts.map +1 -1
  226. package/dist/esm/globalPartitionEndpointManager.js +13 -9
  227. package/dist/esm/globalPartitionEndpointManager.js.map +1 -1
  228. package/dist/esm/request/RequestHandler.js +2 -2
  229. package/dist/esm/request/RequestHandler.js.map +1 -1
  230. package/dist/esm/request/SharedOptions.d.ts +5 -0
  231. package/dist/esm/request/SharedOptions.d.ts.map +1 -1
  232. package/dist/esm/request/SharedOptions.js.map +1 -1
  233. package/dist/esm/retry/retryUtility.d.ts.map +1 -1
  234. package/dist/esm/retry/retryUtility.js +17 -3
  235. package/dist/esm/retry/retryUtility.js.map +1 -1
  236. package/dist/esm/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  237. package/dist/esm/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  238. package/dist/esm/retry/timeoutFailoverRetryPolicy.js +4 -4
  239. package/dist/esm/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  240. package/dist/esm/utils/encode.d.ts +1 -1
  241. package/dist/esm/utils/encode.d.ts.map +1 -1
  242. package/dist/esm/utils/encode.js.map +1 -1
  243. package/dist/react-native/ClientContext.d.ts.map +1 -1
  244. package/dist/react-native/ClientContext.js +110 -19
  245. package/dist/react-native/ClientContext.js.map +1 -1
  246. package/dist/react-native/CosmosClient.d.ts +13 -0
  247. package/dist/react-native/CosmosClient.d.ts.map +1 -1
  248. package/dist/react-native/CosmosClient.js +19 -3
  249. package/dist/react-native/CosmosClient.js.map +1 -1
  250. package/dist/react-native/CosmosClientOptions.d.ts.map +1 -1
  251. package/dist/react-native/CosmosClientOptions.js.map +1 -1
  252. package/dist/react-native/CosmosDiagnostics.d.ts +4 -0
  253. package/dist/react-native/CosmosDiagnostics.d.ts.map +1 -1
  254. package/dist/react-native/CosmosDiagnostics.js.map +1 -1
  255. package/dist/react-native/GlobalEndpointManagerOptions.d.ts +2 -0
  256. package/dist/react-native/GlobalEndpointManagerOptions.d.ts.map +1 -0
  257. package/dist/react-native/GlobalEndpointManagerOptions.js +2 -0
  258. package/dist/react-native/GlobalEndpointManagerOptions.js.map +1 -0
  259. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.d.ts.map +1 -1
  260. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.js +3 -0
  261. package/dist/react-native/client/ChangeFeed/ChangeFeedForEpkRange.js.map +1 -1
  262. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.d.ts.map +1 -1
  263. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.js +3 -0
  264. package/dist/react-native/client/ChangeFeed/ChangeFeedForPartitionKey.js.map +1 -1
  265. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts +5 -0
  266. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.d.ts.map +1 -1
  267. package/dist/react-native/client/ChangeFeed/ChangeFeedIteratorOptions.js.map +1 -1
  268. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.d.ts +1 -0
  269. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.d.ts.map +1 -1
  270. package/dist/react-native/client/ChangeFeed/InternalChangeFeedOptions.js.map +1 -1
  271. package/dist/react-native/client/ChangeFeed/changeFeedUtils.d.ts.map +1 -1
  272. package/dist/react-native/client/ChangeFeed/changeFeedUtils.js +1 -0
  273. package/dist/react-native/client/ChangeFeed/changeFeedUtils.js.map +1 -1
  274. package/dist/react-native/client/Item/Items.d.ts.map +1 -1
  275. package/dist/react-native/client/Item/Items.js +5 -0
  276. package/dist/react-native/client/Item/Items.js.map +1 -1
  277. package/dist/react-native/common/constants.d.ts +4 -0
  278. package/dist/react-native/common/constants.d.ts.map +1 -1
  279. package/dist/react-native/common/constants.js +5 -1
  280. package/dist/react-native/common/constants.js.map +1 -1
  281. package/dist/react-native/common/helper.d.ts +6 -0
  282. package/dist/react-native/common/helper.d.ts.map +1 -1
  283. package/dist/react-native/common/helper.js +9 -1
  284. package/dist/react-native/common/helper.js.map +1 -1
  285. package/dist/react-native/common/platform.d.ts +1 -0
  286. package/dist/react-native/common/platform.d.ts.map +1 -1
  287. package/dist/react-native/common/platform.js +1 -3
  288. package/dist/react-native/common/platform.js.map +1 -1
  289. package/dist/react-native/diagnostics/DiagnosticNodeInternal.d.ts +1 -0
  290. package/dist/react-native/diagnostics/DiagnosticNodeInternal.d.ts.map +1 -1
  291. package/dist/react-native/diagnostics/DiagnosticNodeInternal.js.map +1 -1
  292. package/dist/react-native/documents/ConnectionPolicy.d.ts +10 -4
  293. package/dist/react-native/documents/ConnectionPolicy.d.ts.map +1 -1
  294. package/dist/react-native/documents/ConnectionPolicy.js +2 -2
  295. package/dist/react-native/documents/ConnectionPolicy.js.map +1 -1
  296. package/dist/react-native/documents/DatabaseAccount.d.ts +4 -0
  297. package/dist/react-native/documents/DatabaseAccount.d.ts.map +1 -1
  298. package/dist/react-native/documents/DatabaseAccount.js +9 -0
  299. package/dist/react-native/documents/DatabaseAccount.js.map +1 -1
  300. package/dist/react-native/globalEndpointManager.d.ts +8 -0
  301. package/dist/react-native/globalEndpointManager.d.ts.map +1 -1
  302. package/dist/react-native/globalEndpointManager.js +68 -6
  303. package/dist/react-native/globalEndpointManager.js.map +1 -1
  304. package/dist/react-native/globalPartitionEndpointManager.d.ts +0 -2
  305. package/dist/react-native/globalPartitionEndpointManager.d.ts.map +1 -1
  306. package/dist/react-native/globalPartitionEndpointManager.js +13 -9
  307. package/dist/react-native/globalPartitionEndpointManager.js.map +1 -1
  308. package/dist/react-native/request/RequestHandler.js +2 -2
  309. package/dist/react-native/request/RequestHandler.js.map +1 -1
  310. package/dist/react-native/request/SharedOptions.d.ts +5 -0
  311. package/dist/react-native/request/SharedOptions.d.ts.map +1 -1
  312. package/dist/react-native/request/SharedOptions.js.map +1 -1
  313. package/dist/react-native/retry/retryUtility.d.ts.map +1 -1
  314. package/dist/react-native/retry/retryUtility.js +17 -3
  315. package/dist/react-native/retry/retryUtility.js.map +1 -1
  316. package/dist/react-native/retry/timeoutFailoverRetryPolicy.d.ts +1 -2
  317. package/dist/react-native/retry/timeoutFailoverRetryPolicy.d.ts.map +1 -1
  318. package/dist/react-native/retry/timeoutFailoverRetryPolicy.js +4 -4
  319. package/dist/react-native/retry/timeoutFailoverRetryPolicy.js.map +1 -1
  320. package/dist/react-native/utils/encode.d.ts +1 -1
  321. package/dist/react-native/utils/encode.d.ts.map +1 -1
  322. package/dist/react-native/utils/encode.js.map +1 -1
  323. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionPolicy.js","sourceRoot":"","sources":["../../../src/documents/ConnectionPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAoCrD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAqB,MAAM,CAAC,MAAM,CAAC;IACrE,cAAc,EAAE,cAAc,CAAC,OAAO;IACtC,cAAc,EAAE,KAAK;IACrB,uBAAuB,EAAE,IAAI;IAC7B,kBAAkB,EAAE,EAAE;IACtB,YAAY,EAAE;QACZ,oBAAoB,EAAE,SAAS,CAAC,oCAAoC;QACpE,gCAAgC,EAAE,SAAS,CAAC,sCAAsC;QAClF,oBAAoB,EAAE,SAAS,CAAC,oCAAoC;KACrE;IACD,yBAAyB,EAAE,IAAI;IAC/B,uBAAuB,EAAE,MAAM;IAC/B,kCAAkC,EAAE,IAAI;IACxC,4BAA4B,EAAE,KAAK;IACnC,kCAAkC,EAAE,KAAK;CAC1C,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/constants.js\";\nimport type { RetryOptions } from \"../retry/retryOptions.js\";\nimport { ConnectionMode } from \"./ConnectionMode.js\";\n/**\n * Represents the Connection policy associated with a CosmosClient in the Azure Cosmos DB database service.\n */\nexport interface ConnectionPolicy {\n /** Determines which mode to connect to Cosmos with. (Currently only supports Gateway option) */\n connectionMode?: ConnectionMode;\n /** Request timeout (time to wait for response from network peer). Represented in milliseconds. */\n requestTimeout?: number;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations. Default true.\n * Required to call client.dispose() when this is set to true after destroying the CosmosClient inside another process or in the browser.\n */\n enableEndpointDiscovery?: boolean;\n /** List of azure regions to be used as preferred locations for read requests. */\n preferredLocations?: string[];\n /** RetryOptions object which defines several configurable properties used during retry. */\n retryOptions?: RetryOptions;\n /**\n * The flag that enables writes on any locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service.\n * Default is `true`.\n */\n useMultipleWriteLocations?: boolean;\n /** Rate in milliseconds at which the client will refresh the endpoints list in the background */\n endpointRefreshRateInMs?: number;\n /** Flag to enable/disable background refreshing of endpoints. Defaults to true.\n * Endpoint discovery using `enableEndpointsDiscovery` will still work for failed requests. */\n enableBackgroundEndpointRefreshing?: boolean;\n /** Flag to enable/disable the Per Partition Level Failover (PPAF). Defaults to false\n * If enablePartitionLevelFailover is set to true, by default enablePartitionLevelCircuitBreaker\n * will also be set to true. This is done to improve the read availability and latency.*/\n enablePartitionLevelFailover?: boolean;\n /** Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB). Defaults to false */\n enablePartitionLevelCircuitBreaker?: boolean;\n}\n\n/**\n * @hidden\n */\nexport const defaultConnectionPolicy: ConnectionPolicy = Object.freeze({\n connectionMode: ConnectionMode.Gateway,\n requestTimeout: 60000,\n enableEndpointDiscovery: true,\n preferredLocations: [],\n retryOptions: {\n maxRetryAttemptCount: Constants.ThrottledRequestMaxRetryAttemptCount,\n fixedRetryIntervalInMilliseconds: Constants.ThrottledRequestFixedRetryIntervalInMs,\n maxWaitTimeInSeconds: Constants.ThrottledRequestMaxWaitTimeInSeconds,\n },\n useMultipleWriteLocations: true,\n endpointRefreshRateInMs: 300000,\n enableBackgroundEndpointRefreshing: true,\n enablePartitionLevelFailover: false,\n enablePartitionLevelCircuitBreaker: false,\n});\n"]}
1
+ {"version":3,"file":"ConnectionPolicy.js","sourceRoot":"","sources":["../../../src/documents/ConnectionPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA2CrD;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAqB,MAAM,CAAC,MAAM,CAAC;IACrE,cAAc,EAAE,cAAc,CAAC,OAAO;IACtC,cAAc,EAAE,KAAK;IACrB,uBAAuB,EAAE,IAAI;IAC7B,kBAAkB,EAAE,EAAE;IACtB,YAAY,EAAE;QACZ,oBAAoB,EAAE,SAAS,CAAC,oCAAoC;QACpE,gCAAgC,EAAE,SAAS,CAAC,sCAAsC;QAClF,oBAAoB,EAAE,SAAS,CAAC,oCAAoC;KACrE;IACD,yBAAyB,EAAE,IAAI;IAC/B,uBAAuB,EAAE,MAAM;IAC/B,kCAAkC,EAAE,IAAI;IACxC,4BAA4B,EAAE,IAAI;IAClC,kCAAkC,EAAE,IAAI;CACzC,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/constants.js\";\nimport type { RetryOptions } from \"../retry/retryOptions.js\";\nimport { ConnectionMode } from \"./ConnectionMode.js\";\n/**\n * Represents the Connection policy associated with a CosmosClient in the Azure Cosmos DB database service.\n */\nexport interface ConnectionPolicy {\n /** Determines which mode to connect to Cosmos with. (Currently only supports Gateway option) */\n connectionMode?: ConnectionMode;\n /** Request timeout (time to wait for response from network peer). Represented in milliseconds. */\n requestTimeout?: number;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations. Default true.\n * Required to call client.dispose() when this is set to true after destroying the CosmosClient inside another process or in the browser.\n */\n enableEndpointDiscovery?: boolean;\n /** List of azure regions to be used as preferred locations for read requests. */\n preferredLocations?: string[];\n /** RetryOptions object which defines several configurable properties used during retry. */\n retryOptions?: RetryOptions;\n /**\n * The flag that enables writes on any locations (regions) for geo-replicated database accounts in the Azure Cosmos DB service.\n * Default is `true`.\n */\n useMultipleWriteLocations?: boolean;\n /** Rate in milliseconds at which the client will refresh the endpoints list in the background */\n endpointRefreshRateInMs?: number;\n /** Flag to enable/disable background refreshing of endpoints. Defaults to true.\n * Endpoint discovery using `enableEndpointsDiscovery` will still work for failed requests. */\n enableBackgroundEndpointRefreshing?: boolean;\n /**\n * Flag to enable/disable Per Partition Level Failover (PPAF). Defaults to true.\n * Automatically failovers to other available partitions when a partition becomes unavailable.\n * When enabled, enablePartitionLevelCircuitBreaker will also be set to true.\n * Note: Requires enableEndpointDiscovery to be true. Has no effect when endpoint discovery is disabled.\n */\n enablePartitionLevelFailover?: boolean;\n\n /**\n * Flag to enable/disable Per Partition Level Circuit Breaker (PPCB). Defaults to true.\n * Note: Requires enableEndpointDiscovery to be true. Has no effect when endpoint discovery is disabled.\n */\n enablePartitionLevelCircuitBreaker?: boolean;\n}\n\n/**\n * @hidden\n */\nexport const defaultConnectionPolicy: ConnectionPolicy = Object.freeze({\n connectionMode: ConnectionMode.Gateway,\n requestTimeout: 60000,\n enableEndpointDiscovery: true,\n preferredLocations: [],\n retryOptions: {\n maxRetryAttemptCount: Constants.ThrottledRequestMaxRetryAttemptCount,\n fixedRetryIntervalInMilliseconds: Constants.ThrottledRequestFixedRetryIntervalInMs,\n maxWaitTimeInSeconds: Constants.ThrottledRequestMaxWaitTimeInSeconds,\n },\n useMultipleWriteLocations: true,\n endpointRefreshRateInMs: 300000,\n enableBackgroundEndpointRefreshing: true,\n enablePartitionLevelFailover: true,\n enablePartitionLevelCircuitBreaker: true,\n});\n"]}
@@ -53,6 +53,10 @@ export declare class DatabaseAccount {
53
53
  /** Gets the UserConsistencyPolicy settings. */
54
54
  readonly consistencyPolicy: ConsistencyLevel;
55
55
  readonly enableMultipleWritableLocations: boolean;
56
+ /**
57
+ * Indicates whether per-partition failover behavior is enabled for the database account.
58
+ */
59
+ readonly enablePerPartitionFailover: boolean;
56
60
  constructor(body: {
57
61
  [key: string]: any;
58
62
  }, headers: CosmosHeaders);
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseAccount.d.ts","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IAC1B,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD;;;OAGG;IACH,IAAW,aAAa,IAAI,MAAM,CAEjC;IACD,0DAA0D;IAC1D,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC;;;OAGG;IACH,IAAW,SAAS,IAAI,MAAM,CAE7B;IACD,sDAAsD;IACtD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IACD,kFAAkF;IAClF,SAAgB,wBAAwB,EAAE,MAAM,CAAC;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B,IAAI,MAAM,CAEhD;IACD;;;;;OAKG;IACH,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IACrD;;;OAGG;IACH,IAAW,iBAAiB,IAAI,gBAAgB,CAE/C;IACD,+CAA+C;IAC/C,SAAgB,iBAAiB,EAAE,gBAAgB,CAAC;IACpD,SAAgB,+BAA+B,EAAE,OAAO,CAAC;gBAGtC,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,OAAO,EAAE,aAAa;CAsBxE;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C"}
1
+ {"version":3,"file":"DatabaseAccount.d.ts","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IAC1B,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,QAAQ,EAAE,CAAM;IACnD;;;OAGG;IACH,IAAW,aAAa,IAAI,MAAM,CAEjC;IACD,0DAA0D;IAC1D,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC;;;OAGG;IACH,IAAW,SAAS,IAAI,MAAM,CAE7B;IACD,sDAAsD;IACtD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IACD,kFAAkF;IAClF,SAAgB,wBAAwB,EAAE,MAAM,CAAC;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B,IAAI,MAAM,CAEhD;IACD;;;;;OAKG;IACH,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IACrD;;;OAGG;IACH,IAAW,iBAAiB,IAAI,gBAAgB,CAE/C;IACD,+CAA+C;IAC/C,SAAgB,iBAAiB,EAAE,gBAAgB,CAAC;IACpD,SAAgB,+BAA+B,EAAE,OAAO,CAAC;IACzD;;OAEG;IACH,SAAgB,0BAA0B,EAAE,OAAO,CAAS;gBAGzC,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,OAAO,EAAE,aAAa;CA2BxE;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C"}
@@ -65,6 +65,10 @@ export class DatabaseAccount {
65
65
  /** Gets the UserConsistencyPolicy settings. */
66
66
  consistencyPolicy;
67
67
  enableMultipleWritableLocations;
68
+ /**
69
+ * Indicates whether per-partition failover behavior is enabled for the database account.
70
+ */
71
+ enablePerPartitionFailover = false;
68
72
  // TODO: body - any
69
73
  constructor(body, headers) {
70
74
  this.databasesLink = "/dbs/";
@@ -88,6 +92,11 @@ export class DatabaseAccount {
88
92
  else {
89
93
  this.enableMultipleWritableLocations = false;
90
94
  }
95
+ if (body[Constants.EnablePerPartitionFailover]) {
96
+ this.enablePerPartitionFailover =
97
+ body[Constants.EnablePerPartitionFailover] === true ||
98
+ body[Constants.EnablePerPartitionFailover] === "true";
99
+ }
91
100
  }
92
101
  }
93
102
  //# sourceMappingURL=DatabaseAccount.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatabaseAccount.js","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,eAAe;IAC1B,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD;;;OAGG;IACH,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,0DAA0D;IAC1C,aAAa,CAAS;IACtC;;;OAGG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,sDAAsD;IACtC,SAAS,CAAS;IAClC;;;OAGG;IACH,IAAW,wBAAwB;QACjC,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;IACD,kFAAkF;IAClE,wBAAwB,CAAS;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B;QACrC,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;IACD;;;;;OAKG;IACa,4BAA4B,CAAS;IACrD;;;OAGG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IACD,+CAA+C;IAC/B,iBAAiB,CAAmB;IACpC,+BAA+B,CAAU;IAEzD,mBAAmB;IACnB,YAAmB,IAA4B,EAAE,OAAsB;QACrE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QACxF,IAAI,CAAC,4BAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;QAChG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB;YACjD,CAAC,CAAE,IAAI,CAAC,qBAAqB,CAAC,uBAA4C;YAC1E,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,+BAA+B;gBAClC,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,KAAK,IAAI;oBAC3D,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,KAAK,MAAM,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,+BAA+B,GAAG,KAAK,CAAC;QAC/C,CAAC;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/index.js\";\nimport type { CosmosHeaders } from \"../queryExecutionContext/index.js\";\nimport { ConsistencyLevel } from \"./ConsistencyLevel.js\";\n\n/**\n * Represents a DatabaseAccount in the Azure Cosmos DB database service.\n */\nexport class DatabaseAccount {\n /** The list of writable locations for a geo-replicated database account. */\n public readonly writableLocations: Location[] = [];\n /** The list of readable locations for a geo-replicated database account. */\n public readonly readableLocations: Location[] = [];\n /**\n * The self-link for Databases in the databaseAccount.\n * @deprecated Use `databasesLink`\n */\n public get DatabasesLink(): string {\n return this.databasesLink;\n }\n /** The self-link for Databases in the databaseAccount. */\n public readonly databasesLink: string;\n /**\n * The self-link for Media in the databaseAccount.\n * @deprecated Use `mediaLink`\n */\n public get MediaLink(): string {\n return this.mediaLink;\n }\n /** The self-link for Media in the databaseAccount. */\n public readonly mediaLink: string;\n /**\n * Attachment content (media) storage quota in MBs ( Retrieved from gateway ).\n * @deprecated use `maxMediaStorageUsageInMB`\n */\n public get MaxMediaStorageUsageInMB(): number {\n return this.maxMediaStorageUsageInMB;\n }\n /** Attachment content (media) storage quota in MBs ( Retrieved from gateway ). */\n public readonly maxMediaStorageUsageInMB: number;\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n *\n * @deprecated use `currentMediaStorageUsageInMB`\n */\n public get CurrentMediaStorageUsageInMB(): number {\n return this.currentMediaStorageUsageInMB;\n }\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n */\n public readonly currentMediaStorageUsageInMB: number;\n /**\n * Gets the UserConsistencyPolicy settings.\n * @deprecated use `consistencyPolicy`\n */\n public get ConsistencyPolicy(): ConsistencyLevel {\n return this.consistencyPolicy;\n }\n /** Gets the UserConsistencyPolicy settings. */\n public readonly consistencyPolicy: ConsistencyLevel;\n public readonly enableMultipleWritableLocations: boolean;\n\n // TODO: body - any\n public constructor(body: { [key: string]: any }, headers: CosmosHeaders) {\n this.databasesLink = \"/dbs/\";\n this.mediaLink = \"/media/\";\n this.maxMediaStorageUsageInMB = headers[Constants.HttpHeaders.MaxMediaStorageUsageInMB];\n this.currentMediaStorageUsageInMB = headers[Constants.HttpHeaders.CurrentMediaStorageUsageInMB];\n this.consistencyPolicy = body.userConsistencyPolicy\n ? (body.userConsistencyPolicy.defaultConsistencyLevel as ConsistencyLevel)\n : ConsistencyLevel.Session;\n if (body[Constants.WritableLocations] && body.id !== \"localhost\") {\n this.writableLocations = body[Constants.WritableLocations] as Location[];\n }\n if (body[Constants.ReadableLocations] && body.id !== \"localhost\") {\n this.readableLocations = body[Constants.ReadableLocations] as Location[];\n }\n if (body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS]) {\n this.enableMultipleWritableLocations =\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === true ||\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === \"true\";\n } else {\n this.enableMultipleWritableLocations = false;\n }\n }\n}\n\n/**\n * Used to specify the locations that are available, read is index 1 and write is index 0.\n */\nexport interface Location {\n name: string;\n databaseAccountEndpoint: string;\n unavailable?: boolean;\n lastUnavailabilityTimestampInMs?: number;\n}\n"]}
1
+ {"version":3,"file":"DatabaseAccount.js","sourceRoot":"","sources":["../../../src/documents/DatabaseAccount.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,OAAO,eAAe;IAC1B,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD,4EAA4E;IAC5D,iBAAiB,GAAe,EAAE,CAAC;IACnD;;;OAGG;IACH,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,0DAA0D;IAC1C,aAAa,CAAS;IACtC;;;OAGG;IACH,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,sDAAsD;IACtC,SAAS,CAAS;IAClC;;;OAGG;IACH,IAAW,wBAAwB;QACjC,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;IACD,kFAAkF;IAClE,wBAAwB,CAAS;IACjD;;;;;;;OAOG;IACH,IAAW,4BAA4B;QACrC,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;IACD;;;;;OAKG;IACa,4BAA4B,CAAS;IACrD;;;OAGG;IACH,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IACD,+CAA+C;IAC/B,iBAAiB,CAAmB;IACpC,+BAA+B,CAAU;IACzD;;OAEG;IACa,0BAA0B,GAAY,KAAK,CAAC;IAE5D,mBAAmB;IACnB,YAAmB,IAA4B,EAAE,OAAsB;QACrE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QACxF,IAAI,CAAC,4BAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;QAChG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,qBAAqB;YACjD,CAAC,CAAE,IAAI,CAAC,qBAAqB,CAAC,uBAA4C;YAC1E,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC7B,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,EAAE,CAAC;YACjE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAe,CAAC;QAC3E,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,+BAA+B;gBAClC,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,KAAK,IAAI;oBAC3D,IAAI,CAAC,SAAS,CAAC,kCAAkC,CAAC,KAAK,MAAM,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,+BAA+B,GAAG,KAAK,CAAC;QAC/C,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,0BAA0B;gBAC7B,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,KAAK,IAAI;oBACnD,IAAI,CAAC,SAAS,CAAC,0BAA0B,CAAC,KAAK,MAAM,CAAC;QAC1D,CAAC;IACH,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Constants } from \"../common/index.js\";\nimport type { CosmosHeaders } from \"../queryExecutionContext/index.js\";\nimport { ConsistencyLevel } from \"./ConsistencyLevel.js\";\n\n/**\n * Represents a DatabaseAccount in the Azure Cosmos DB database service.\n */\nexport class DatabaseAccount {\n /** The list of writable locations for a geo-replicated database account. */\n public readonly writableLocations: Location[] = [];\n /** The list of readable locations for a geo-replicated database account. */\n public readonly readableLocations: Location[] = [];\n /**\n * The self-link for Databases in the databaseAccount.\n * @deprecated Use `databasesLink`\n */\n public get DatabasesLink(): string {\n return this.databasesLink;\n }\n /** The self-link for Databases in the databaseAccount. */\n public readonly databasesLink: string;\n /**\n * The self-link for Media in the databaseAccount.\n * @deprecated Use `mediaLink`\n */\n public get MediaLink(): string {\n return this.mediaLink;\n }\n /** The self-link for Media in the databaseAccount. */\n public readonly mediaLink: string;\n /**\n * Attachment content (media) storage quota in MBs ( Retrieved from gateway ).\n * @deprecated use `maxMediaStorageUsageInMB`\n */\n public get MaxMediaStorageUsageInMB(): number {\n return this.maxMediaStorageUsageInMB;\n }\n /** Attachment content (media) storage quota in MBs ( Retrieved from gateway ). */\n public readonly maxMediaStorageUsageInMB: number;\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n *\n * @deprecated use `currentMediaStorageUsageInMB`\n */\n public get CurrentMediaStorageUsageInMB(): number {\n return this.currentMediaStorageUsageInMB;\n }\n /**\n * Current attachment content (media) usage in MBs (Retrieved from gateway )\n *\n * Value is returned from cached information updated periodically and is not guaranteed\n * to be real time.\n */\n public readonly currentMediaStorageUsageInMB: number;\n /**\n * Gets the UserConsistencyPolicy settings.\n * @deprecated use `consistencyPolicy`\n */\n public get ConsistencyPolicy(): ConsistencyLevel {\n return this.consistencyPolicy;\n }\n /** Gets the UserConsistencyPolicy settings. */\n public readonly consistencyPolicy: ConsistencyLevel;\n public readonly enableMultipleWritableLocations: boolean;\n /**\n * Indicates whether per-partition failover behavior is enabled for the database account.\n */\n public readonly enablePerPartitionFailover: boolean = false;\n\n // TODO: body - any\n public constructor(body: { [key: string]: any }, headers: CosmosHeaders) {\n this.databasesLink = \"/dbs/\";\n this.mediaLink = \"/media/\";\n this.maxMediaStorageUsageInMB = headers[Constants.HttpHeaders.MaxMediaStorageUsageInMB];\n this.currentMediaStorageUsageInMB = headers[Constants.HttpHeaders.CurrentMediaStorageUsageInMB];\n this.consistencyPolicy = body.userConsistencyPolicy\n ? (body.userConsistencyPolicy.defaultConsistencyLevel as ConsistencyLevel)\n : ConsistencyLevel.Session;\n if (body[Constants.WritableLocations] && body.id !== \"localhost\") {\n this.writableLocations = body[Constants.WritableLocations] as Location[];\n }\n if (body[Constants.ReadableLocations] && body.id !== \"localhost\") {\n this.readableLocations = body[Constants.ReadableLocations] as Location[];\n }\n if (body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS]) {\n this.enableMultipleWritableLocations =\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === true ||\n body[Constants.ENABLE_MULTIPLE_WRITABLE_LOCATIONS] === \"true\";\n } else {\n this.enableMultipleWritableLocations = false;\n }\n if (body[Constants.EnablePerPartitionFailover]) {\n this.enablePerPartitionFailover =\n body[Constants.EnablePerPartitionFailover] === true ||\n body[Constants.EnablePerPartitionFailover] === \"true\";\n }\n }\n}\n\n/**\n * Used to specify the locations that are available, read is index 1 and write is index 0.\n */\nexport interface Location {\n name: string;\n databaseAccountEndpoint: string;\n unavailable?: boolean;\n lastUnavailabilityTimestampInMs?: number;\n}\n"]}
@@ -44,6 +44,8 @@ export declare class GlobalEndpointManager {
44
44
  markCurrentLocationUnavailableForRead(diagnosticNode: DiagnosticNodeInternal, endpoint: string): Promise<void>;
45
45
  markCurrentLocationUnavailableForWrite(diagnosticNode: DiagnosticNodeInternal, endpoint: string): Promise<void>;
46
46
  canUseMultipleWriteLocations(resourceType?: ResourceType, operationType?: OperationType): boolean;
47
+ private getEffectiveExcludedLocations;
48
+ private filterExcludedLocations;
47
49
  resolveServiceEndpoint(diagnosticNode: DiagnosticNodeInternal, resourceType: ResourceType, operationType: OperationType, startServiceEndpointIndex?: number): Promise<string>;
48
50
  /**
49
51
  * Refreshes the endpoint list by clearning stale unavailability and then
@@ -75,5 +77,11 @@ export declare class GlobalEndpointManager {
75
77
  * @param locationName - The location name for the azure region like "East US".
76
78
  */
77
79
  private static getLocationalEndpoint;
80
+ /**
81
+ * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag
82
+ * based on the value from database account.
83
+ * @param enablePerPartitionFailover - value from database account
84
+ */
85
+ private refreshPPAFFeatureFlag;
78
86
  }
79
87
  //# sourceMappingURL=globalEndpointManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"globalEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAKtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAItF;;;GAGG;AACH,qBAAa,qBAAqB;IA4B9B,OAAO,CAAC,mBAAmB;IA3B7B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAChC;;OAEG;IACI,uBAAuB,EAAE,OAAO,CAAC;IACxC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,OAAO,CAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAW;IACrC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,4BAA4B,CAAkB;IACtD,OAAO,CAAC,6BAA6B,CAAkB;IACvD,OAAO,CAAC,4BAA4B,CAAU;IAEvC,uBAAuB,EAAE,MAAM,CAAC;IAoBvC;;OAEG;IACU,eAAe,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrF;;OAEG;IACU,gBAAgB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIlD,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIhE;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAIpD,qCAAqC,CAChD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAUH,sCAAsC,CACjD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYT,4BAA4B,CACjC,YAAY,CAAC,EAAE,YAAY,EAC3B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO;IAcG,sBAAsB,CACjC,cAAc,EAAE,sBAAsB,EACtC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,yBAAyB,GAAE,MAAU,GACpC,OAAO,CAAC,MAAM,CAAC;IAyElB;;;;;OAKG;IACU,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,gCAAgC;IAexC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,4BAA4B;IAQpC;;;;OAIG;YACW,iCAAiC;IAuC/C;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;CA4BrC"}
1
+ {"version":3,"file":"globalEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAE/E,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAMtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAKtF;;;GAGG;AACH,qBAAa,qBAAqB;IAuC9B,OAAO,CAAC,mBAAmB;IAtC7B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAChC;;OAEG;IACI,uBAAuB,EAAE,OAAO,CAAC;IACxC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,OAAO,CAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAW;IACrC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,4BAA4B,CAAkB;IACtD,OAAO,CAAC,6BAA6B,CAAkB;IACvD,OAAO,CAAC,4BAA4B,CAAU;IAEvC,uBAAuB,EAAE,MAAM,CAAC;IAmCvC;;OAEG;IACU,eAAe,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrF;;OAEG;IACU,gBAAgB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIlD,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAIhE;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAIpD,qCAAqC,CAChD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAUH,sCAAsC,CACjD,cAAc,EAAE,sBAAsB,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYT,4BAA4B,CACjC,YAAY,CAAC,EAAE,YAAY,EAC3B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO;IAcV,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,uBAAuB;IAalB,sBAAsB,CACjC,cAAc,EAAE,sBAAsB,EACtC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,yBAAyB,GAAE,MAAU,GACpC,OAAO,CAAC,MAAM,CAAC;IAmHlB;;;;;OAKG;IACU,mBAAmB,CAAC,cAAc,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,gCAAgC;IAexC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,4BAA4B;IAQpC;;;;OAIG;YACW,iCAAiC;IAuC/C;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IA6BpC;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;CAQ/B"}
@@ -5,6 +5,7 @@ import { Constants } from "./common/constants.js";
5
5
  import { MetadataLookUpType } from "./CosmosDiagnostics.js";
6
6
  import { withMetadataDiagnostics } from "./utils/diagnostics.js";
7
7
  import { normalizeEndpoint } from "./utils/checkURL.js";
8
+ import { canApplyExcludedLocations } from "./common/helper.js";
8
9
  /**
9
10
  * @hidden
10
11
  * This internal class implements the logic for endpoint management for geo-replicated database accounts.
@@ -31,6 +32,16 @@ export class GlobalEndpointManager {
31
32
  unavailableWriteableLocations = [];
32
33
  enableMultipleWriteLocations;
33
34
  preferredLocationsCount;
35
+ /**
36
+ * Flag to enable/disable the Per Partition Level Failover (PPAF)
37
+ * @internal
38
+ */
39
+ enablePartitionLevelFailover;
40
+ /**
41
+ * Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB)
42
+ * @internal
43
+ */
44
+ enablePartitionLevelCircuitBreaker;
34
45
  /**
35
46
  * @param options - The document client instance.
36
47
  * @internal
@@ -43,6 +54,10 @@ export class GlobalEndpointManager {
43
54
  this.isRefreshing = false;
44
55
  this.preferredLocations = this.options.connectionPolicy.preferredLocations;
45
56
  this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;
57
+ this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;
58
+ this.enablePartitionLevelCircuitBreaker =
59
+ options.connectionPolicy.enablePartitionLevelCircuitBreaker ||
60
+ options.connectionPolicy.enablePartitionLevelFailover;
46
61
  }
47
62
  /**
48
63
  * Gets the current read endpoint from the endpoint cache.
@@ -96,7 +111,35 @@ export class GlobalEndpointManager {
96
111
  }
97
112
  return canUse;
98
113
  }
114
+ getEffectiveExcludedLocations(excludedLocations = [], resourceType) {
115
+ if (!canApplyExcludedLocations(resourceType)) {
116
+ return new Set();
117
+ }
118
+ return excludedLocations.length ? new Set(excludedLocations.map(normalizeEndpoint)) : new Set();
119
+ }
120
+ filterExcludedLocations(preferredLocations, excludedLocations) {
121
+ if (!excludedLocations || excludedLocations.size === 0) {
122
+ return preferredLocations;
123
+ }
124
+ const filteredLocations = preferredLocations.filter((location) => {
125
+ return !excludedLocations.has(normalizeEndpoint(location));
126
+ });
127
+ return filteredLocations;
128
+ }
99
129
  async resolveServiceEndpoint(diagnosticNode, resourceType, operationType, startServiceEndpointIndex = 0) {
130
+ return this.resolveServiceEndpointInternal({
131
+ diagnosticNode: diagnosticNode,
132
+ resourceType: resourceType,
133
+ operationType: operationType,
134
+ startServiceEndpointIndex: startServiceEndpointIndex,
135
+ });
136
+ }
137
+ /**
138
+ * @internal
139
+ */
140
+ async resolveServiceEndpointInternal(resolveServiceEndpointOptions) {
141
+ // Extract all fields from ResolveServiceEndpointOptions
142
+ const { diagnosticNode, resourceType, operationType, startServiceEndpointIndex, excludedLocations = [], } = resolveServiceEndpointOptions;
100
143
  // If endpoint discovery is disabled, always use the user provided endpoint
101
144
  if (!this.options.connectionPolicy.enableEndpointDiscovery) {
102
145
  diagnosticNode.addData({ readFromCache: true }, "default_endpoint");
@@ -118,17 +161,23 @@ export class GlobalEndpointManager {
118
161
  this.writeableLocations = resourceResponse.resource.writableLocations;
119
162
  this.readableLocations = resourceResponse.resource.readableLocations;
120
163
  this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;
164
+ this.refreshPPAFFeatureFlag(resourceResponse.resource.enablePerPartitionFailover);
121
165
  }
122
166
  const locations = isReadRequest(operationType)
123
167
  ? this.readableLocations
124
168
  : this.writeableLocations;
169
+ const effectiveExcludedLocations = this.getEffectiveExcludedLocations(excludedLocations, resourceType);
170
+ diagnosticNode.addData({ excludedLocations: Array.from(effectiveExcludedLocations) }, "excluded_locations");
171
+ // Filter locations based on exclusions
172
+ const availableLocations = this.filterExcludedLocations(this.preferredLocations, effectiveExcludedLocations);
125
173
  let location;
126
174
  // If we have preferred locations, try each one in order and use the first available one
127
- if (this.preferredLocations &&
128
- this.preferredLocations.length > 0 &&
129
- startServiceEndpointIndex < this.preferredLocations.length) {
130
- for (let i = startServiceEndpointIndex; i < this.preferredLocations.length; i++) {
131
- const preferredLocation = this.preferredLocations[i];
175
+ if (availableLocations &&
176
+ availableLocations.length > 0 &&
177
+ startServiceEndpointIndex < availableLocations.length) {
178
+ this.preferredLocationsCount = availableLocations.length;
179
+ for (let i = startServiceEndpointIndex; i < availableLocations.length; i++) {
180
+ const preferredLocation = availableLocations[i];
132
181
  location = locations.find((loc) => loc.unavailable !== true &&
133
182
  normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation));
134
183
  if (location) {
@@ -143,7 +192,7 @@ export class GlobalEndpointManager {
143
192
  ? locations.slice(startServiceEndpointIndex)
144
193
  : locations;
145
194
  location = locationsToSearch.find((loc) => {
146
- return loc.unavailable !== true;
195
+ return (loc.unavailable !== true && !effectiveExcludedLocations.has(normalizeEndpoint(loc.name)));
147
196
  });
148
197
  }
149
198
  location = location ? location : { name: "", databaseAccountEndpoint: this.defaultEndpoint };
@@ -274,5 +323,18 @@ export class GlobalEndpointManager {
274
323
  }
275
324
  return null;
276
325
  }
326
+ /**
327
+ * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag
328
+ * based on the value from database account.
329
+ * @param enablePerPartitionFailover - value from database account
330
+ */
331
+ refreshPPAFFeatureFlag(enablePerPartitionFailover) {
332
+ // If the enablePartitionLevelFailover is true, but PPAF is not enabled on the account,
333
+ // we will override it to false.
334
+ if (enablePerPartitionFailover === false) {
335
+ this.enablePartitionLevelFailover = enablePerPartitionFailover;
336
+ this.enablePartitionLevelCircuitBreaker = enablePerPartitionFailover;
337
+ }
338
+ }
277
339
  }
278
340
  //# sourceMappingURL=globalEndpointManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"globalEndpointManager.js","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport type { CosmosClientOptions } from \"./CosmosClientOptions.js\";\nimport type { Location, DatabaseAccount } from \"./documents/index.js\";\nimport type { RequestOptions } from \"./index.js\";\nimport { Constants } from \"./common/constants.js\";\nimport type { ResourceResponse } from \"./request/index.js\";\nimport { MetadataLookUpType } from \"./CosmosDiagnostics.js\";\nimport type { DiagnosticNodeInternal } from \"./diagnostics/DiagnosticNodeInternal.js\";\nimport { withMetadataDiagnostics } from \"./utils/diagnostics.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\n\n/**\n * @hidden\n * This internal class implements the logic for endpoint management for geo-replicated database accounts.\n */\nexport class GlobalEndpointManager {\n /**\n * The endpoint used to create the client instance.\n */\n private defaultEndpoint: string;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations.\n */\n public enableEndpointDiscovery: boolean;\n private isRefreshing: boolean;\n private options: CosmosClientOptions;\n /**\n * List of azure regions to be used as preferred locations for read requests.\n */\n private preferredLocations: string[];\n private writeableLocations: Location[] = [];\n private readableLocations: Location[] = [];\n private unavailableReadableLocations: Location[] = [];\n private unavailableWriteableLocations: Location[] = [];\n private enableMultipleWriteLocations: boolean;\n\n public preferredLocationsCount: number;\n /**\n * @param options - The document client instance.\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private readDatabaseAccount: (\n diagnosticNode: DiagnosticNodeInternal,\n opts: RequestOptions,\n ) => Promise<ResourceResponse<DatabaseAccount>>,\n ) {\n this.options = options;\n this.defaultEndpoint = options.endpoint;\n this.enableEndpointDiscovery = options.connectionPolicy.enableEndpointDiscovery;\n this.isRefreshing = false;\n this.preferredLocations = this.options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n }\n\n /**\n * Gets the current read endpoint from the endpoint cache.\n */\n public async getReadEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Read);\n }\n\n /**\n * Gets the current write endpoint from the endpoint cache.\n */\n public async getWriteEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Replace);\n }\n\n public async getReadEndpoints(): Promise<ReadonlyArray<string>> {\n return this.readableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n public async getWriteEndpoints(): Promise<ReadonlyArray<string>> {\n return this.writeableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n /**\n * Gets the read locations from the endpoint cache.\n */\n public async getReadLocations(): Promise<ReadonlyArray<Location>> {\n return this.readableLocations;\n }\n\n public async markCurrentLocationUnavailableForRead(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.readableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableReadableLocations.push(location);\n }\n }\n\n public async markCurrentLocationUnavailableForWrite(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.writeableLocations.find(\n (loc) => loc.databaseAccountEndpoint === endpoint,\n );\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableWriteableLocations.push(location);\n }\n }\n\n public canUseMultipleWriteLocations(\n resourceType?: ResourceType,\n operationType?: OperationType,\n ): boolean {\n let canUse =\n this.options.connectionPolicy.useMultipleWriteLocations && this.enableMultipleWriteLocations;\n\n if (resourceType) {\n canUse =\n canUse &&\n (resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute));\n }\n\n return canUse;\n }\n\n public async resolveServiceEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n resourceType: ResourceType,\n operationType: OperationType,\n startServiceEndpointIndex: number = 0, // Represents the starting index for selecting servers.\n ): Promise<string> {\n // If endpoint discovery is disabled, always use the user provided endpoint\n\n if (!this.options.connectionPolicy.enableEndpointDiscovery) {\n diagnosticNode.addData({ readFromCache: true }, \"default_endpoint\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n // If getting the database account, always use the user provided endpoint\n if (resourceType === ResourceType.none) {\n diagnosticNode.addData({ readFromCache: true }, \"none_resource\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n if (this.readableLocations.length === 0 || this.writeableLocations.length === 0) {\n const resourceResponse = await withMetadataDiagnostics(\n async (metadataNode: DiagnosticNodeInternal) => {\n return this.readDatabaseAccount(metadataNode, {\n urlConnection: this.defaultEndpoint,\n });\n },\n diagnosticNode,\n MetadataLookUpType.DatabaseAccountLookUp,\n );\n\n this.writeableLocations = resourceResponse.resource.writableLocations;\n this.readableLocations = resourceResponse.resource.readableLocations;\n this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;\n }\n\n const locations = isReadRequest(operationType)\n ? this.readableLocations\n : this.writeableLocations;\n\n let location;\n // If we have preferred locations, try each one in order and use the first available one\n if (\n this.preferredLocations &&\n this.preferredLocations.length > 0 &&\n startServiceEndpointIndex < this.preferredLocations.length\n ) {\n for (let i = startServiceEndpointIndex; i < this.preferredLocations.length; i++) {\n const preferredLocation = this.preferredLocations[i];\n location = locations.find(\n (loc) =>\n loc.unavailable !== true &&\n normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n break;\n }\n }\n }\n\n // If no preferred locations or one did not match, just grab the first one that is available\n if (!location) {\n const startIndexValid =\n startServiceEndpointIndex >= 0 && startServiceEndpointIndex < locations.length;\n const locationsToSearch = startIndexValid\n ? locations.slice(startServiceEndpointIndex)\n : locations;\n location = locationsToSearch.find((loc) => {\n return loc.unavailable !== true;\n });\n }\n\n location = location ? location : { name: \"\", databaseAccountEndpoint: this.defaultEndpoint };\n diagnosticNode.recordEndpointResolution(location.databaseAccountEndpoint);\n return location.databaseAccountEndpoint;\n }\n\n /**\n * Refreshes the endpoint list by clearning stale unavailability and then\n * retrieving the writable and readable locations from the geo-replicated database account\n * and then updating the locations cache.\n * We skip the refreshing if enableEndpointDiscovery is set to False\n */\n public async refreshEndpointList(diagnosticNode: DiagnosticNodeInternal): Promise<void> {\n if (!this.isRefreshing && this.enableEndpointDiscovery) {\n this.isRefreshing = true;\n const databaseAccount = await this.getDatabaseAccountFromAnyEndpoint(diagnosticNode);\n if (databaseAccount) {\n this.refreshStaleUnavailableLocations();\n this.refreshEndpoints(databaseAccount);\n }\n this.isRefreshing = false;\n }\n }\n\n private refreshEndpoints(databaseAccount: DatabaseAccount): void {\n const oldWritableLocations = this.writeableLocations;\n const oldReadableLocations = this.readableLocations;\n\n function merge(loc: Location, oldList: Location[]): Location {\n const prev = oldList.find((o) => o.name === loc.name);\n if (prev) {\n loc.unavailable = prev.unavailable;\n loc.lastUnavailabilityTimestampInMs = prev.lastUnavailabilityTimestampInMs;\n }\n return loc;\n }\n\n this.writeableLocations = databaseAccount.writableLocations.map((loc) =>\n merge({ ...loc }, oldWritableLocations),\n );\n this.readableLocations = databaseAccount.readableLocations.map((loc) =>\n merge({ ...loc }, oldReadableLocations),\n );\n }\n\n private refreshStaleUnavailableLocations(): void {\n const now = Date.now();\n this.updateLocation(now, this.unavailableReadableLocations, this.readableLocations);\n this.unavailableReadableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableReadableLocations,\n );\n\n this.updateLocation(now, this.unavailableWriteableLocations, this.writeableLocations);\n this.unavailableWriteableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableWriteableLocations,\n );\n }\n\n /**\n * update the locationUnavailability to undefined if the location is available again\n * @param now - current time\n * @param unavailableLocations - list of unavailable locations\n * @param allLocations - list of all locations\n */\n private updateLocation(\n now: number,\n unavailableLocations: Location[],\n allLocations: Location[],\n ): void {\n for (const location of unavailableLocations) {\n const unavailableLocation = allLocations.find((loc) => loc.name === location.name);\n if (\n unavailableLocation &&\n now - unavailableLocation.lastUnavailabilityTimestampInMs >\n Constants.LocationUnavailableExpirationTimeInMs\n ) {\n unavailableLocation.unavailable = false;\n }\n }\n }\n\n private cleanUnavailableLocationList(now: number, unavailableLocations: Location[]): Location[] {\n return unavailableLocations.filter((loc) => {\n return (\n now - loc.lastUnavailabilityTimestampInMs < Constants.LocationUnavailableExpirationTimeInMs\n );\n });\n }\n\n /**\n * Gets the database account first by using the default endpoint, and if that doesn't returns\n * use the endpoints for the preferred locations in the order they are specified to get\n * the database account.\n */\n private async getDatabaseAccountFromAnyEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<DatabaseAccount> {\n try {\n const options = { urlConnection: this.defaultEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(diagnosticNode, options);\n return databaseAccount;\n // If for any reason(non - globaldb related), we are not able to get the database\n // account from the above call to readDatabaseAccount,\n // we would try to get this information from any of the preferred locations that the user\n // might have specified (by creating a locational endpoint)\n // and keeping eating the exception until we get the database account and return None at the end,\n // if we are not able to get that info from any endpoints\n } catch (err: any) {\n // TODO: Tracing\n }\n\n if (this.preferredLocations) {\n for (const location of this.preferredLocations) {\n try {\n const locationalEndpoint = GlobalEndpointManager.getLocationalEndpoint(\n this.defaultEndpoint,\n location,\n );\n const options = { urlConnection: locationalEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(\n diagnosticNode,\n options,\n );\n if (databaseAccount) {\n return databaseAccount;\n }\n } catch (err: any) {\n // TODO: Tracing\n }\n }\n }\n }\n\n /**\n * Gets the locational endpoint using the location name passed to it using the default endpoint.\n *\n * @param defaultEndpoint - The default endpoint to use for the endpoint.\n * @param locationName - The location name for the azure region like \"East US\".\n */\n private static getLocationalEndpoint(defaultEndpoint: string, locationName: string): string {\n // For defaultEndpoint like 'https://contoso.documents.azure.com:443/' parse it to generate URL format\n // This defaultEndpoint should be global endpoint(and cannot be a locational endpoint)\n // and we agreed to document that\n const endpointUrl = new URL(defaultEndpoint);\n\n // hostname attribute in endpointUrl will return 'contoso.documents.azure.com'\n if (endpointUrl.hostname) {\n const hostnameParts = endpointUrl.hostname.toString().toLowerCase().split(\".\");\n if (hostnameParts) {\n // globalDatabaseAccountName will return 'contoso'\n const globalDatabaseAccountName = hostnameParts[0];\n\n // Prepare the locationalDatabaseAccountName as contoso-EastUS for location_name 'East US'\n const locationalDatabaseAccountName =\n globalDatabaseAccountName + \"-\" + locationName.replace(\" \", \"\");\n\n // Replace 'contoso' with 'contoso-EastUS' and\n // return locationalEndpoint as https://contoso-EastUS.documents.azure.com:443/\n const locationalEndpoint = defaultEndpoint\n .toLowerCase()\n .replace(globalDatabaseAccountName, locationalDatabaseAccountName);\n return locationalEndpoint;\n }\n }\n\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"globalEndpointManager.js","sourceRoot":"","sources":["../../src/globalEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport type { CosmosClientOptions } from \"./CosmosClientOptions.js\";\nimport type { Location, DatabaseAccount } from \"./documents/index.js\";\nimport type { RequestOptions } from \"./index.js\";\nimport type { ResolveServiceEndpointOptions } from \"./GlobalEndpointManagerOptions.js\";\nimport { Constants } from \"./common/constants.js\";\nimport type { ResourceResponse } from \"./request/index.js\";\nimport { MetadataLookUpType } from \"./CosmosDiagnostics.js\";\nimport type { DiagnosticNodeInternal } from \"./diagnostics/DiagnosticNodeInternal.js\";\nimport { withMetadataDiagnostics } from \"./utils/diagnostics.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { canApplyExcludedLocations } from \"./common/helper.js\";\n\n/**\n * @hidden\n * This internal class implements the logic for endpoint management for geo-replicated database accounts.\n */\nexport class GlobalEndpointManager {\n /**\n * The endpoint used to create the client instance.\n */\n private defaultEndpoint: string;\n /**\n * Flag to enable/disable automatic redirecting of requests based on read/write operations.\n */\n public enableEndpointDiscovery: boolean;\n private isRefreshing: boolean;\n private options: CosmosClientOptions;\n /**\n * List of azure regions to be used as preferred locations for read requests.\n */\n private preferredLocations: string[];\n private writeableLocations: Location[] = [];\n private readableLocations: Location[] = [];\n private unavailableReadableLocations: Location[] = [];\n private unavailableWriteableLocations: Location[] = [];\n private enableMultipleWriteLocations: boolean;\n\n public preferredLocationsCount: number;\n /**\n * Flag to enable/disable the Per Partition Level Failover (PPAF)\n * @internal\n */\n public enablePartitionLevelFailover: boolean;\n /**\n * Flag to enable/disable the Per Partition Level Circuit Breaker (PPCB)\n * @internal\n */\n public enablePartitionLevelCircuitBreaker: boolean;\n\n /**\n * @param options - The document client instance.\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private readDatabaseAccount: (\n diagnosticNode: DiagnosticNodeInternal,\n opts: RequestOptions,\n ) => Promise<ResourceResponse<DatabaseAccount>>,\n ) {\n this.options = options;\n this.defaultEndpoint = options.endpoint;\n this.enableEndpointDiscovery = options.connectionPolicy.enableEndpointDiscovery;\n this.isRefreshing = false;\n this.preferredLocations = this.options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;\n this.enablePartitionLevelCircuitBreaker =\n options.connectionPolicy.enablePartitionLevelCircuitBreaker ||\n options.connectionPolicy.enablePartitionLevelFailover;\n }\n\n /**\n * Gets the current read endpoint from the endpoint cache.\n */\n public async getReadEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Read);\n }\n\n /**\n * Gets the current write endpoint from the endpoint cache.\n */\n public async getWriteEndpoint(diagnosticNode: DiagnosticNodeInternal): Promise<string> {\n return this.resolveServiceEndpoint(diagnosticNode, ResourceType.item, OperationType.Replace);\n }\n\n public async getReadEndpoints(): Promise<ReadonlyArray<string>> {\n return this.readableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n public async getWriteEndpoints(): Promise<ReadonlyArray<string>> {\n return this.writeableLocations.map((loc) => loc.databaseAccountEndpoint);\n }\n\n /**\n * Gets the read locations from the endpoint cache.\n */\n public async getReadLocations(): Promise<ReadonlyArray<Location>> {\n return this.readableLocations;\n }\n\n public async markCurrentLocationUnavailableForRead(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.readableLocations.find((loc) => loc.databaseAccountEndpoint === endpoint);\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableReadableLocations.push(location);\n }\n }\n\n public async markCurrentLocationUnavailableForWrite(\n diagnosticNode: DiagnosticNodeInternal,\n endpoint: string,\n ): Promise<void> {\n await this.refreshEndpointList(diagnosticNode);\n const location = this.writeableLocations.find(\n (loc) => loc.databaseAccountEndpoint === endpoint,\n );\n if (location) {\n location.unavailable = true;\n location.lastUnavailabilityTimestampInMs = Date.now();\n this.unavailableWriteableLocations.push(location);\n }\n }\n\n public canUseMultipleWriteLocations(\n resourceType?: ResourceType,\n operationType?: OperationType,\n ): boolean {\n let canUse =\n this.options.connectionPolicy.useMultipleWriteLocations && this.enableMultipleWriteLocations;\n\n if (resourceType) {\n canUse =\n canUse &&\n (resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute));\n }\n\n return canUse;\n }\n\n private getEffectiveExcludedLocations(\n excludedLocations: string[] = [],\n resourceType: ResourceType,\n ): Set<string> {\n if (!canApplyExcludedLocations(resourceType)) {\n return new Set();\n }\n\n return excludedLocations.length ? new Set(excludedLocations.map(normalizeEndpoint)) : new Set();\n }\n\n private filterExcludedLocations(\n preferredLocations: string[],\n excludedLocations?: Set<string>,\n ): string[] {\n if (!excludedLocations || excludedLocations.size === 0) {\n return preferredLocations;\n }\n const filteredLocations = preferredLocations.filter((location) => {\n return !excludedLocations.has(normalizeEndpoint(location));\n });\n return filteredLocations;\n }\n\n public async resolveServiceEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n resourceType: ResourceType,\n operationType: OperationType,\n startServiceEndpointIndex: number = 0, // Represents the starting index for selecting servers.\n ): Promise<string> {\n return this.resolveServiceEndpointInternal({\n diagnosticNode: diagnosticNode,\n resourceType: resourceType,\n operationType: operationType,\n startServiceEndpointIndex: startServiceEndpointIndex,\n });\n }\n\n /**\n * @internal\n */\n public async resolveServiceEndpointInternal(\n resolveServiceEndpointOptions: ResolveServiceEndpointOptions,\n ): Promise<string> {\n // Extract all fields from ResolveServiceEndpointOptions\n const {\n diagnosticNode,\n resourceType,\n operationType,\n startServiceEndpointIndex,\n excludedLocations = [],\n } = resolveServiceEndpointOptions;\n\n // If endpoint discovery is disabled, always use the user provided endpoint\n\n if (!this.options.connectionPolicy.enableEndpointDiscovery) {\n diagnosticNode.addData({ readFromCache: true }, \"default_endpoint\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n\n // If getting the database account, always use the user provided endpoint\n if (resourceType === ResourceType.none) {\n diagnosticNode.addData({ readFromCache: true }, \"none_resource\");\n diagnosticNode.recordEndpointResolution(this.defaultEndpoint);\n return this.defaultEndpoint;\n }\n if (this.readableLocations.length === 0 || this.writeableLocations.length === 0) {\n const resourceResponse = await withMetadataDiagnostics(\n async (metadataNode: DiagnosticNodeInternal) => {\n return this.readDatabaseAccount(metadataNode, {\n urlConnection: this.defaultEndpoint,\n });\n },\n diagnosticNode,\n MetadataLookUpType.DatabaseAccountLookUp,\n );\n\n this.writeableLocations = resourceResponse.resource.writableLocations;\n this.readableLocations = resourceResponse.resource.readableLocations;\n this.enableMultipleWriteLocations = resourceResponse.resource.enableMultipleWritableLocations;\n this.refreshPPAFFeatureFlag(resourceResponse.resource.enablePerPartitionFailover);\n }\n\n const locations = isReadRequest(operationType)\n ? this.readableLocations\n : this.writeableLocations;\n\n const effectiveExcludedLocations = this.getEffectiveExcludedLocations(\n excludedLocations,\n resourceType,\n );\n diagnosticNode.addData(\n { excludedLocations: Array.from(effectiveExcludedLocations) },\n \"excluded_locations\",\n );\n\n // Filter locations based on exclusions\n const availableLocations = this.filterExcludedLocations(\n this.preferredLocations,\n effectiveExcludedLocations,\n );\n\n let location;\n // If we have preferred locations, try each one in order and use the first available one\n if (\n availableLocations &&\n availableLocations.length > 0 &&\n startServiceEndpointIndex < availableLocations.length\n ) {\n this.preferredLocationsCount = availableLocations.length;\n\n for (let i = startServiceEndpointIndex; i < availableLocations.length; i++) {\n const preferredLocation = availableLocations[i];\n location = locations.find(\n (loc) =>\n loc.unavailable !== true &&\n normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n break;\n }\n }\n }\n\n // If no preferred locations or one did not match, just grab the first one that is available\n if (!location) {\n const startIndexValid =\n startServiceEndpointIndex >= 0 && startServiceEndpointIndex < locations.length;\n const locationsToSearch = startIndexValid\n ? locations.slice(startServiceEndpointIndex)\n : locations;\n location = locationsToSearch.find((loc) => {\n return (\n loc.unavailable !== true && !effectiveExcludedLocations.has(normalizeEndpoint(loc.name))\n );\n });\n }\n\n location = location ? location : { name: \"\", databaseAccountEndpoint: this.defaultEndpoint };\n diagnosticNode.recordEndpointResolution(location.databaseAccountEndpoint);\n return location.databaseAccountEndpoint;\n }\n\n /**\n * Refreshes the endpoint list by clearning stale unavailability and then\n * retrieving the writable and readable locations from the geo-replicated database account\n * and then updating the locations cache.\n * We skip the refreshing if enableEndpointDiscovery is set to False\n */\n public async refreshEndpointList(diagnosticNode: DiagnosticNodeInternal): Promise<void> {\n if (!this.isRefreshing && this.enableEndpointDiscovery) {\n this.isRefreshing = true;\n const databaseAccount = await this.getDatabaseAccountFromAnyEndpoint(diagnosticNode);\n if (databaseAccount) {\n this.refreshStaleUnavailableLocations();\n this.refreshEndpoints(databaseAccount);\n }\n this.isRefreshing = false;\n }\n }\n\n private refreshEndpoints(databaseAccount: DatabaseAccount): void {\n const oldWritableLocations = this.writeableLocations;\n const oldReadableLocations = this.readableLocations;\n\n function merge(loc: Location, oldList: Location[]): Location {\n const prev = oldList.find((o) => o.name === loc.name);\n if (prev) {\n loc.unavailable = prev.unavailable;\n loc.lastUnavailabilityTimestampInMs = prev.lastUnavailabilityTimestampInMs;\n }\n return loc;\n }\n\n this.writeableLocations = databaseAccount.writableLocations.map((loc) =>\n merge({ ...loc }, oldWritableLocations),\n );\n this.readableLocations = databaseAccount.readableLocations.map((loc) =>\n merge({ ...loc }, oldReadableLocations),\n );\n }\n\n private refreshStaleUnavailableLocations(): void {\n const now = Date.now();\n this.updateLocation(now, this.unavailableReadableLocations, this.readableLocations);\n this.unavailableReadableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableReadableLocations,\n );\n\n this.updateLocation(now, this.unavailableWriteableLocations, this.writeableLocations);\n this.unavailableWriteableLocations = this.cleanUnavailableLocationList(\n now,\n this.unavailableWriteableLocations,\n );\n }\n\n /**\n * update the locationUnavailability to undefined if the location is available again\n * @param now - current time\n * @param unavailableLocations - list of unavailable locations\n * @param allLocations - list of all locations\n */\n private updateLocation(\n now: number,\n unavailableLocations: Location[],\n allLocations: Location[],\n ): void {\n for (const location of unavailableLocations) {\n const unavailableLocation = allLocations.find((loc) => loc.name === location.name);\n if (\n unavailableLocation &&\n now - unavailableLocation.lastUnavailabilityTimestampInMs >\n Constants.LocationUnavailableExpirationTimeInMs\n ) {\n unavailableLocation.unavailable = false;\n }\n }\n }\n\n private cleanUnavailableLocationList(now: number, unavailableLocations: Location[]): Location[] {\n return unavailableLocations.filter((loc) => {\n return (\n now - loc.lastUnavailabilityTimestampInMs < Constants.LocationUnavailableExpirationTimeInMs\n );\n });\n }\n\n /**\n * Gets the database account first by using the default endpoint, and if that doesn't returns\n * use the endpoints for the preferred locations in the order they are specified to get\n * the database account.\n */\n private async getDatabaseAccountFromAnyEndpoint(\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<DatabaseAccount> {\n try {\n const options = { urlConnection: this.defaultEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(diagnosticNode, options);\n return databaseAccount;\n // If for any reason(non - globaldb related), we are not able to get the database\n // account from the above call to readDatabaseAccount,\n // we would try to get this information from any of the preferred locations that the user\n // might have specified (by creating a locational endpoint)\n // and keeping eating the exception until we get the database account and return None at the end,\n // if we are not able to get that info from any endpoints\n } catch (err: any) {\n // TODO: Tracing\n }\n\n if (this.preferredLocations) {\n for (const location of this.preferredLocations) {\n try {\n const locationalEndpoint = GlobalEndpointManager.getLocationalEndpoint(\n this.defaultEndpoint,\n location,\n );\n const options = { urlConnection: locationalEndpoint };\n const { resource: databaseAccount } = await this.readDatabaseAccount(\n diagnosticNode,\n options,\n );\n if (databaseAccount) {\n return databaseAccount;\n }\n } catch (err: any) {\n // TODO: Tracing\n }\n }\n }\n }\n\n /**\n * Gets the locational endpoint using the location name passed to it using the default endpoint.\n *\n * @param defaultEndpoint - The default endpoint to use for the endpoint.\n * @param locationName - The location name for the azure region like \"East US\".\n */\n private static getLocationalEndpoint(defaultEndpoint: string, locationName: string): string {\n // For defaultEndpoint like 'https://contoso.documents.azure.com:443/' parse it to generate URL format\n // This defaultEndpoint should be global endpoint(and cannot be a locational endpoint)\n // and we agreed to document that\n const endpointUrl = new URL(defaultEndpoint);\n\n // hostname attribute in endpointUrl will return 'contoso.documents.azure.com'\n if (endpointUrl.hostname) {\n const hostnameParts = endpointUrl.hostname.toString().toLowerCase().split(\".\");\n if (hostnameParts) {\n // globalDatabaseAccountName will return 'contoso'\n const globalDatabaseAccountName = hostnameParts[0];\n\n // Prepare the locationalDatabaseAccountName as contoso-EastUS for location_name 'East US'\n const locationalDatabaseAccountName =\n globalDatabaseAccountName + \"-\" + locationName.replace(\" \", \"\");\n\n // Replace 'contoso' with 'contoso-EastUS' and\n // return locationalEndpoint as https://contoso-EastUS.documents.azure.com:443/\n const locationalEndpoint = defaultEndpoint\n .toLowerCase()\n .replace(globalDatabaseAccountName, locationalDatabaseAccountName);\n return locationalEndpoint;\n }\n }\n\n return null;\n }\n\n /**\n * Refreshes the enablePartitionLevelFailover and enablePartitionLevelCircuitBreaker flag\n * based on the value from database account.\n * @param enablePerPartitionFailover - value from database account\n */\n private refreshPPAFFeatureFlag(enablePerPartitionFailover: boolean): void {\n // If the enablePartitionLevelFailover is true, but PPAF is not enabled on the account,\n // we will override it to false.\n if (enablePerPartitionFailover === false) {\n this.enablePartitionLevelFailover = enablePerPartitionFailover;\n this.enablePartitionLevelCircuitBreaker = enablePerPartitionFailover;\n }\n }\n}\n"]}
@@ -7,8 +7,6 @@ export declare class GlobalPartitionEndpointManager {
7
7
  private globalEndpointManager;
8
8
  private readonly partitionKeyRangeToLocationForWrite;
9
9
  private readonly partitionKeyRangeToLocationForReadAndWrite;
10
- private enablePartitionLevelFailover;
11
- private enablePartitionLevelCircuitBreaker;
12
10
  private preferredLocations;
13
11
  preferredLocationsCount: number;
14
12
  private circuitBreakerFailbackBackgroundRefresher;
@@ -1 +1 @@
1
- {"version":3,"file":"globalPartitionEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,sBAAsB,EAGtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,qBAAa,8BAA8B;IAiBvC,OAAO,CAAC,qBAAqB;IAhB/B,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAA6C;IACjG,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAGzD;IACF,OAAO,CAAC,4BAA4B,CAAU;IAC9C,OAAO,CAAC,kCAAkC,CAAU;IACpD,OAAO,CAAC,kBAAkB,CAAW;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IACvC,OAAO,CAAC,yCAAyC,CAAiB;IA2BlE;;;;OAIG;IACU,yBAAyB,CACpC,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;IA6BnB;;;OAGG;IACU,oCAAoC,CAC/C,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,cAAc,CAAC;IAiC1B;;;OAGG;IACI,OAAO,IAAI,IAAI;YAMR,8CAA8C;IA2D5D;;;OAGG;YACW,uCAAuC;IA6CrD,yEAAyE;YAC3D,qCAAqC;IA2BnD,0FAA0F;YAC5E,qCAAqC;IAmBnD;;;;OAIG;IACH,OAAO,CAAC,iDAAiD;IAazD;;;;OAIG;IACH,OAAO,CAAC,gDAAgD;IAexD;;;;;;OAMG;YACW,wDAAwD;IA8BtE;;;;;;;;OAQG;IACH,OAAO,CAAC,kCAAkC;IAU1C;;;;;OAKG;YACW,8CAA8C;CAmB7D"}
1
+ {"version":3,"file":"globalPartitionEndpointManager.d.ts","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,sBAAsB,EAGtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAMpB;;;GAGG;AACH,qBAAa,8BAA8B;IAevC,OAAO,CAAC,qBAAqB;IAd/B,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAA6C;IACjG,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAGzD;IACF,OAAO,CAAC,kBAAkB,CAAW;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IACvC,OAAO,CAAC,yCAAyC,CAAiB;IAwBlE;;;;OAIG;IACU,yBAAyB,CACpC,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,OAAO,CAAC;IA6BnB;;;OAGG;IACU,oCAAoC,CAC/C,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,sBAAsB,GACrC,OAAO,CAAC,cAAc,CAAC;IAiC1B;;;OAGG;IACI,OAAO,IAAI,IAAI;YAMR,8CAA8C;IA2D5D;;;OAGG;YACW,uCAAuC;IA6CrD,yEAAyE;YAC3D,qCAAqC;IA2BnD,0FAA0F;YAC5E,qCAAqC;IAmBnD;;;;OAIG;IACH,OAAO,CAAC,iDAAiD;IAazD;;;;OAIG;IACH,OAAO,CAAC,gDAAgD;IAkBxD;;;;;;OAMG;YACW,wDAAwD;IA8BtE;;;;;;;;OAQG;IACH,OAAO,CAAC,kCAAkC;IAU1C;;;;;OAKG;YACW,8CAA8C;CA4B7D"}
@@ -14,8 +14,6 @@ export class GlobalPartitionEndpointManager {
14
14
  globalEndpointManager;
15
15
  partitionKeyRangeToLocationForWrite;
16
16
  partitionKeyRangeToLocationForReadAndWrite;
17
- enablePartitionLevelFailover;
18
- enablePartitionLevelCircuitBreaker;
19
17
  preferredLocations;
20
18
  preferredLocationsCount;
21
19
  circuitBreakerFailbackBackgroundRefresher;
@@ -26,13 +24,10 @@ export class GlobalPartitionEndpointManager {
26
24
  this.globalEndpointManager = globalEndpointManager;
27
25
  this.partitionKeyRangeToLocationForWrite = new Map();
28
26
  this.partitionKeyRangeToLocationForReadAndWrite = new Map();
29
- this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;
30
- this.enablePartitionLevelCircuitBreaker =
31
- options.connectionPolicy.enablePartitionLevelCircuitBreaker ||
32
- options.connectionPolicy.enablePartitionLevelFailover;
33
27
  this.preferredLocations = options.connectionPolicy.preferredLocations;
34
28
  this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;
35
- if (this.enablePartitionLevelCircuitBreaker) {
29
+ if (this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
30
+ this.globalEndpointManager.enablePartitionLevelFailover) {
36
31
  this.initiateCircuitBreakerFailbackLoop();
37
32
  }
38
33
  }
@@ -202,7 +197,7 @@ export class GlobalPartitionEndpointManager {
202
197
  * and the global endpoint manager cannot use multiple write locations for the request.
203
198
  */
204
199
  isRequestEligibleForPerPartitionAutomaticFailover(requestContext) {
205
- return (this.enablePartitionLevelFailover &&
200
+ return (this.globalEndpointManager.enablePartitionLevelFailover &&
206
201
  !isReadRequest(requestContext.operationType) &&
207
202
  !this.globalEndpointManager.canUseMultipleWriteLocations(requestContext.resourceType, requestContext.operationType));
208
203
  }
@@ -212,7 +207,9 @@ export class GlobalPartitionEndpointManager {
212
207
  * the global endpoint manager can use multiple write locations for the request.
213
208
  */
214
209
  isRequestEligibleForPartitionLevelCircuitBreaker(requestContext) {
215
- if (!this.enablePartitionLevelCircuitBreaker) {
210
+ const enablePartitionLevelCircuitBreaker = this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
211
+ this.globalEndpointManager.enablePartitionLevelFailover;
212
+ if (!enablePartitionLevelCircuitBreaker) {
216
213
  return false;
217
214
  }
218
215
  if (isReadRequest(requestContext.operationType)) {
@@ -268,6 +265,13 @@ export class GlobalPartitionEndpointManager {
268
265
  * location for the partition key range.
269
266
  */
270
267
  async openConnectionToUnhealthyEndpointsWithFailback() {
268
+ // If partition level circuit breaker or failover is not enabled, dispose the timer.
269
+ const enablePartitionLevelCircuitBreaker = this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||
270
+ this.globalEndpointManager.enablePartitionLevelFailover;
271
+ if (!enablePartitionLevelCircuitBreaker) {
272
+ this.dispose();
273
+ return;
274
+ }
271
275
  for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {
272
276
  const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);
273
277
  if (!partitionFailover)
@@ -1 +1 @@
1
- {"version":3,"file":"globalPartitionEndpointManager.js","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport {\n Constants,\n DiagnosticNodeInternal,\n type CosmosClientOptions,\n type GlobalEndpointManager,\n type RequestContext,\n} from \"./index.js\";\nimport { PartitionKeyRangeFailoverInfo } from \"./PartitionKeyRangeFailoverInfo.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { startBackgroundTask } from \"./utils/time.js\";\nimport { assertNotUndefined } from \"./utils/typeChecks.js\";\n\n/**\n * @hidden\n * This class is used to failover single partitions to different regions.\n */\nexport class GlobalPartitionEndpointManager {\n private readonly partitionKeyRangeToLocationForWrite: Map<string, PartitionKeyRangeFailoverInfo>;\n private readonly partitionKeyRangeToLocationForReadAndWrite: Map<\n string,\n PartitionKeyRangeFailoverInfo\n >;\n private enablePartitionLevelFailover: boolean;\n private enablePartitionLevelCircuitBreaker: boolean;\n private preferredLocations: string[];\n public preferredLocationsCount: number;\n private circuitBreakerFailbackBackgroundRefresher: NodeJS.Timeout;\n\n /**\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private globalEndpointManager: GlobalEndpointManager,\n ) {\n this.partitionKeyRangeToLocationForWrite = new Map<string, PartitionKeyRangeFailoverInfo>();\n this.partitionKeyRangeToLocationForReadAndWrite = new Map<\n string,\n PartitionKeyRangeFailoverInfo\n >();\n\n this.enablePartitionLevelFailover = options.connectionPolicy.enablePartitionLevelFailover;\n this.enablePartitionLevelCircuitBreaker =\n options.connectionPolicy.enablePartitionLevelCircuitBreaker ||\n options.connectionPolicy.enablePartitionLevelFailover;\n\n this.preferredLocations = options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n if (this.enablePartitionLevelCircuitBreaker) {\n this.initiateCircuitBreakerFailbackLoop();\n }\n }\n\n /**\n * Checks eligibility of the request for partition failover and\n * tries to mark the endpoint unavailable for the partition key range. Future\n * requests will be routed to the next location if available.\n */\n public async tryPartitionLevelFailover(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, true))) {\n return false;\n }\n\n const isRequestEligibleForPerPartitionAutomaticFailover =\n this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext);\n const isRequestEligibleForPartitionLevelCircuitBreaker =\n this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext);\n\n if (\n isRequestEligibleForPerPartitionAutomaticFailover ||\n (isRequestEligibleForPartitionLevelCircuitBreaker &&\n (await this.incrementFailureCounterAndCheckFailover(\n requestContext,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n )))\n ) {\n return this.tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext,\n diagnosticNode,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n );\n }\n return false;\n }\n\n /**\n * Updates the DocumentServiceRequest routing location to point\n * new a location based if a partition level failover occurred.\n */\n public async tryAddPartitionLevelLocationOverride(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<RequestContext> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, false))) {\n return requestContext;\n }\n\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n\n if (this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext)) {\n if (this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n const partitionFailOver = this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n } else if (this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext)) {\n if (this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n const partitionFailOver =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n\n const canCircuitBreakerTriggerPartitionFailOver =\n await partitionFailOver.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n if (canCircuitBreakerTriggerPartitionFailOver) {\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n }\n }\n return requestContext;\n }\n\n /**\n * This method clears the background refresher for circuit breaker failback\n * and stops the periodic checks for unhealthy endpoints.\n */\n public dispose(): void {\n if (this.circuitBreakerFailbackBackgroundRefresher) {\n clearTimeout(this.circuitBreakerFailbackBackgroundRefresher);\n }\n }\n\n private async tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n\n const readLocations = await this.globalEndpointManager.getReadLocations();\n const readEndPoints: string[] = [];\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n // For any single master write accounts, the next locations to fail over will be the read regions configured at the account level.\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForWrite,\n diagnosticNode,\n );\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n // For the read requests or multi-master write requests, the next locations to fail over will be the preferred locations\n // configured at the account level plus any other read locations that are not already in the preferred locations.\n if (this.preferredLocations && this.preferredLocations.length > 0) {\n for (const preferredLocation of this.preferredLocations) {\n const location = readLocations.find(\n (loc) => normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n\n // Add the rest of the locations not already added\n for (const location of readLocations) {\n if (!readEndPoints.includes(location.databaseAccountEndpoint)) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n } else {\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForReadAndWrite,\n diagnosticNode,\n );\n }\n return false;\n }\n\n /**\n * Increments the failure counter for the specified partition and checks if the partition can fail over.\n * This method is used to determine if a partition should be failed over based on the number of request failures.\n */\n private async incrementFailureCounterAndCheckFailover(\n requestContext: RequestContext,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n let partitionKeyRangeFailoverInfo: PartitionKeyRangeFailoverInfo;\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n if (!this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n if (!this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForReadAndWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n } else {\n return false;\n }\n\n assertNotUndefined(\n partitionKeyRangeFailoverInfo,\n \"partitionKeyRangeFailoverInfo should be set if failover flags are true.\",\n );\n\n const currentTimeInMilliseconds = Date.now();\n await partitionKeyRangeFailoverInfo.incrementRequestFailureCounts(\n isReadRequest(requestContext.operationType),\n currentTimeInMilliseconds,\n );\n\n return partitionKeyRangeFailoverInfo.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n }\n\n /** Validates if the given request is eligible for partition failover. */\n private async isRequestEligibleForPartitionFailover(\n requestContext: RequestContext,\n shouldValidateFailedLocation: boolean,\n ): Promise<boolean> {\n if (\n !requestContext ||\n !requestContext.operationType ||\n !requestContext.resourceType ||\n !requestContext.partitionKeyRangeId\n ) {\n return false;\n }\n\n const canUsePartitionLevelFailoverLocations = await this.canUsePartitionLevelFailoverLocations(\n requestContext.operationType,\n requestContext.resourceType,\n );\n if (!canUsePartitionLevelFailoverLocations) {\n return false;\n }\n\n if (shouldValidateFailedLocation && !requestContext.endpoint) {\n return false;\n }\n return true;\n }\n\n /** Determines if partition level failover locations can be used for the given request. */\n private async canUsePartitionLevelFailoverLocations(\n operationType?: OperationType,\n resourceType?: ResourceType,\n ): Promise<boolean> {\n const readEndPoints = await this.globalEndpointManager.getReadEndpoints();\n if (readEndPoints.length <= 1) {\n return false;\n }\n if (\n resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute)\n ) {\n // Right now, for single-master only reads are supported for circuit breaker, and writes are supported for automatic.\n // failover. For multi master, both reads and writes are supported. Hence return true for both the cases.\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a request is eligible for per-partition automatic failover.\n * A request is eligible if it is a write request, partition level failover is enabled,\n * and the global endpoint manager cannot use multiple write locations for the request.\n */\n private isRequestEligibleForPerPartitionAutomaticFailover(\n requestContext: RequestContext,\n ): boolean {\n return (\n this.enablePartitionLevelFailover &&\n !isReadRequest(requestContext.operationType) &&\n !this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n )\n );\n }\n\n /**\n * Determines if a request is eligible for partition-level circuit breaker.\n * This method checks if partition-level circuit breaker is enabled, and if the request is a read-only request or\n * the global endpoint manager can use multiple write locations for the request.\n */\n private isRequestEligibleForPartitionLevelCircuitBreaker(\n requestContext: RequestContext,\n ): boolean {\n if (!this.enablePartitionLevelCircuitBreaker) {\n return false;\n }\n if (isReadRequest(requestContext.operationType)) {\n return true;\n }\n return this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n );\n }\n\n /**\n * Attempts to add or update the partition failover information and move to the next available location.\n * This method checks if the current location for the partition key range has failed and updates the failover\n * information to route the request to the next available location. If all locations have been tried, it removes\n * the failover information for the partition key range. Return True if the failover information was successfully\n * updated and the request was routed to a new location, otherwise false.\n */\n private async tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId: string,\n failedEndPoint: string,\n nextEndPoints: readonly string[],\n partitionKeyRangeToLocation: Map<string, PartitionKeyRangeFailoverInfo>,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!partitionKeyRangeToLocation.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n partitionKeyRangeToLocation.set(partitionKeyRangeId, failoverInfo);\n }\n const partitionFailOver = partitionKeyRangeToLocation.get(partitionKeyRangeId);\n\n // Will return true if it was able to update to a new region\n if (\n await partitionFailOver.tryMoveNextLocation(\n nextEndPoints,\n failedEndPoint,\n diagnosticNode,\n partitionKeyRangeId,\n )\n ) {\n return true;\n }\n // All the locations have been tried. Remove the override information\n partitionKeyRangeToLocation.delete(partitionKeyRangeId);\n return false;\n }\n\n /**\n * Initiates a background loop that periodically checks for unhealthy endpoints\n * and attempts to open connections to them. If a connection is successfully\n * established, it initiates a failback to the original location for the partition key range.\n * This is useful for scenarios where a partition key range has been marked as unavailable\n * due to a circuit breaker, and we want to periodically check if the original location\n * has become healthy again.\n * The loop runs at a defined interval specified by Constants.StalePartitionUnavailabilityRefreshIntervalInMs.\n */\n private initiateCircuitBreakerFailbackLoop(): void {\n this.circuitBreakerFailbackBackgroundRefresher = startBackgroundTask(async () => {\n try {\n await this.openConnectionToUnhealthyEndpointsWithFailback();\n } catch (err) {\n console.error(\"Failed to open connection to unhealthy endpoints: \", err);\n }\n }, Constants.StalePartitionUnavailabilityRefreshIntervalInMs);\n }\n\n /**\n * Attempts to open connections to unhealthy endpoints and initiates failback if the connections are successful.\n * This method checks the partition key ranges that have failed locations and tries to re-establish connections\n * to those locations. If a connection is successfully re-established, it initiates a failback to the original\n * location for the partition key range.\n */\n private async openConnectionToUnhealthyEndpointsWithFailback(): Promise<void> {\n for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {\n const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);\n if (!partitionFailover) continue;\n\n const { firstRequestFailureTime } =\n await partitionFailover.snapshotPartitionFailoverTimestamps();\n const now = new Date();\n\n if (\n now.getTime() - firstRequestFailureTime >\n Constants.AllowedPartitionUnavailabilityDurationInMs\n ) {\n // Un-deterministically marking the original failed endpoint for the PkRange back to healthy.\n // Initiate Failback to the original failed location.\n this.partitionKeyRangeToLocationForReadAndWrite.delete(pkRange);\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"globalPartitionEndpointManager.js","sourceRoot":"","sources":["../../src/globalPartitionEndpointManager.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { OperationType, ResourceType, isReadRequest } from \"./common/index.js\";\nimport {\n Constants,\n DiagnosticNodeInternal,\n type CosmosClientOptions,\n type GlobalEndpointManager,\n type RequestContext,\n} from \"./index.js\";\nimport { PartitionKeyRangeFailoverInfo } from \"./PartitionKeyRangeFailoverInfo.js\";\nimport { normalizeEndpoint } from \"./utils/checkURL.js\";\nimport { startBackgroundTask } from \"./utils/time.js\";\nimport { assertNotUndefined } from \"./utils/typeChecks.js\";\n\n/**\n * @hidden\n * This class is used to failover single partitions to different regions.\n */\nexport class GlobalPartitionEndpointManager {\n private readonly partitionKeyRangeToLocationForWrite: Map<string, PartitionKeyRangeFailoverInfo>;\n private readonly partitionKeyRangeToLocationForReadAndWrite: Map<\n string,\n PartitionKeyRangeFailoverInfo\n >;\n private preferredLocations: string[];\n public preferredLocationsCount: number;\n private circuitBreakerFailbackBackgroundRefresher: NodeJS.Timeout;\n\n /**\n * @internal\n */\n constructor(\n options: CosmosClientOptions,\n private globalEndpointManager: GlobalEndpointManager,\n ) {\n this.partitionKeyRangeToLocationForWrite = new Map<string, PartitionKeyRangeFailoverInfo>();\n this.partitionKeyRangeToLocationForReadAndWrite = new Map<\n string,\n PartitionKeyRangeFailoverInfo\n >();\n this.preferredLocations = options.connectionPolicy.preferredLocations;\n this.preferredLocationsCount = this.preferredLocations ? this.preferredLocations.length : 0;\n if (\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover\n ) {\n this.initiateCircuitBreakerFailbackLoop();\n }\n }\n\n /**\n * Checks eligibility of the request for partition failover and\n * tries to mark the endpoint unavailable for the partition key range. Future\n * requests will be routed to the next location if available.\n */\n public async tryPartitionLevelFailover(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, true))) {\n return false;\n }\n\n const isRequestEligibleForPerPartitionAutomaticFailover =\n this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext);\n const isRequestEligibleForPartitionLevelCircuitBreaker =\n this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext);\n\n if (\n isRequestEligibleForPerPartitionAutomaticFailover ||\n (isRequestEligibleForPartitionLevelCircuitBreaker &&\n (await this.incrementFailureCounterAndCheckFailover(\n requestContext,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n )))\n ) {\n return this.tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext,\n diagnosticNode,\n isRequestEligibleForPerPartitionAutomaticFailover,\n isRequestEligibleForPartitionLevelCircuitBreaker,\n );\n }\n return false;\n }\n\n /**\n * Updates the DocumentServiceRequest routing location to point\n * new a location based if a partition level failover occurred.\n */\n public async tryAddPartitionLevelLocationOverride(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<RequestContext> {\n if (!(await this.isRequestEligibleForPartitionFailover(requestContext, false))) {\n return requestContext;\n }\n\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n\n if (this.isRequestEligibleForPerPartitionAutomaticFailover(requestContext)) {\n if (this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n const partitionFailOver = this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n } else if (this.isRequestEligibleForPartitionLevelCircuitBreaker(requestContext)) {\n if (this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n const partitionFailOver =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n\n const canCircuitBreakerTriggerPartitionFailOver =\n await partitionFailOver.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n if (canCircuitBreakerTriggerPartitionFailOver) {\n requestContext.endpoint = partitionFailOver.getCurrentEndPoint();\n diagnosticNode.recordEndpointResolution(requestContext.endpoint);\n return requestContext;\n }\n }\n }\n return requestContext;\n }\n\n /**\n * This method clears the background refresher for circuit breaker failback\n * and stops the periodic checks for unhealthy endpoints.\n */\n public dispose(): void {\n if (this.circuitBreakerFailbackBackgroundRefresher) {\n clearTimeout(this.circuitBreakerFailbackBackgroundRefresher);\n }\n }\n\n private async tryMarkEndpointUnavailableForPartitionKeyRange(\n requestContext: RequestContext,\n diagnosticNode: DiagnosticNodeInternal,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n\n const readLocations = await this.globalEndpointManager.getReadLocations();\n const readEndPoints: string[] = [];\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n // For any single master write accounts, the next locations to fail over will be the read regions configured at the account level.\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForWrite,\n diagnosticNode,\n );\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n // For the read requests or multi-master write requests, the next locations to fail over will be the preferred locations\n // configured at the account level plus any other read locations that are not already in the preferred locations.\n if (this.preferredLocations && this.preferredLocations.length > 0) {\n for (const preferredLocation of this.preferredLocations) {\n const location = readLocations.find(\n (loc) => normalizeEndpoint(loc.name) === normalizeEndpoint(preferredLocation),\n );\n if (location) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n\n // Add the rest of the locations not already added\n for (const location of readLocations) {\n if (!readEndPoints.includes(location.databaseAccountEndpoint)) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n } else {\n for (const location of readLocations) {\n readEndPoints.push(location.databaseAccountEndpoint);\n }\n }\n return this.tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId,\n failedEndPoint,\n readEndPoints,\n this.partitionKeyRangeToLocationForReadAndWrite,\n diagnosticNode,\n );\n }\n return false;\n }\n\n /**\n * Increments the failure counter for the specified partition and checks if the partition can fail over.\n * This method is used to determine if a partition should be failed over based on the number of request failures.\n */\n private async incrementFailureCounterAndCheckFailover(\n requestContext: RequestContext,\n isRequestEligibleForPerPartitionAutomaticFailover: boolean,\n isRequestEligibleForPartitionLevelCircuitBreaker: boolean,\n ): Promise<boolean> {\n const partitionKeyRangeId = requestContext.partitionKeyRangeId;\n const failedEndPoint = requestContext.endpoint;\n let partitionKeyRangeFailoverInfo: PartitionKeyRangeFailoverInfo;\n\n if (isRequestEligibleForPerPartitionAutomaticFailover) {\n if (!this.partitionKeyRangeToLocationForWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForWrite.get(partitionKeyRangeId);\n } else if (isRequestEligibleForPartitionLevelCircuitBreaker) {\n if (!this.partitionKeyRangeToLocationForReadAndWrite.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n this.partitionKeyRangeToLocationForReadAndWrite.set(partitionKeyRangeId, failoverInfo);\n }\n partitionKeyRangeFailoverInfo =\n this.partitionKeyRangeToLocationForReadAndWrite.get(partitionKeyRangeId);\n } else {\n return false;\n }\n\n assertNotUndefined(\n partitionKeyRangeFailoverInfo,\n \"partitionKeyRangeFailoverInfo should be set if failover flags are true.\",\n );\n\n const currentTimeInMilliseconds = Date.now();\n await partitionKeyRangeFailoverInfo.incrementRequestFailureCounts(\n isReadRequest(requestContext.operationType),\n currentTimeInMilliseconds,\n );\n\n return partitionKeyRangeFailoverInfo.canCircuitBreakerTriggerPartitionFailOver(\n isReadRequest(requestContext.operationType),\n );\n }\n\n /** Validates if the given request is eligible for partition failover. */\n private async isRequestEligibleForPartitionFailover(\n requestContext: RequestContext,\n shouldValidateFailedLocation: boolean,\n ): Promise<boolean> {\n if (\n !requestContext ||\n !requestContext.operationType ||\n !requestContext.resourceType ||\n !requestContext.partitionKeyRangeId\n ) {\n return false;\n }\n\n const canUsePartitionLevelFailoverLocations = await this.canUsePartitionLevelFailoverLocations(\n requestContext.operationType,\n requestContext.resourceType,\n );\n if (!canUsePartitionLevelFailoverLocations) {\n return false;\n }\n\n if (shouldValidateFailedLocation && !requestContext.endpoint) {\n return false;\n }\n return true;\n }\n\n /** Determines if partition level failover locations can be used for the given request. */\n private async canUsePartitionLevelFailoverLocations(\n operationType?: OperationType,\n resourceType?: ResourceType,\n ): Promise<boolean> {\n const readEndPoints = await this.globalEndpointManager.getReadEndpoints();\n if (readEndPoints.length <= 1) {\n return false;\n }\n if (\n resourceType === ResourceType.item ||\n (resourceType === ResourceType.sproc && operationType === OperationType.Execute)\n ) {\n // Right now, for single-master only reads are supported for circuit breaker, and writes are supported for automatic.\n // failover. For multi master, both reads and writes are supported. Hence return true for both the cases.\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a request is eligible for per-partition automatic failover.\n * A request is eligible if it is a write request, partition level failover is enabled,\n * and the global endpoint manager cannot use multiple write locations for the request.\n */\n private isRequestEligibleForPerPartitionAutomaticFailover(\n requestContext: RequestContext,\n ): boolean {\n return (\n this.globalEndpointManager.enablePartitionLevelFailover &&\n !isReadRequest(requestContext.operationType) &&\n !this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n )\n );\n }\n\n /**\n * Determines if a request is eligible for partition-level circuit breaker.\n * This method checks if partition-level circuit breaker is enabled, and if the request is a read-only request or\n * the global endpoint manager can use multiple write locations for the request.\n */\n private isRequestEligibleForPartitionLevelCircuitBreaker(\n requestContext: RequestContext,\n ): boolean {\n const enablePartitionLevelCircuitBreaker =\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover;\n if (!enablePartitionLevelCircuitBreaker) {\n return false;\n }\n if (isReadRequest(requestContext.operationType)) {\n return true;\n }\n return this.globalEndpointManager.canUseMultipleWriteLocations(\n requestContext.resourceType,\n requestContext.operationType,\n );\n }\n\n /**\n * Attempts to add or update the partition failover information and move to the next available location.\n * This method checks if the current location for the partition key range has failed and updates the failover\n * information to route the request to the next available location. If all locations have been tried, it removes\n * the failover information for the partition key range. Return True if the failover information was successfully\n * updated and the request was routed to a new location, otherwise false.\n */\n private async tryAddOrUpdatePartitionFailoverInfoAndMoveToNextLocation(\n partitionKeyRangeId: string,\n failedEndPoint: string,\n nextEndPoints: readonly string[],\n partitionKeyRangeToLocation: Map<string, PartitionKeyRangeFailoverInfo>,\n diagnosticNode: DiagnosticNodeInternal,\n ): Promise<boolean> {\n if (!partitionKeyRangeToLocation.has(partitionKeyRangeId)) {\n // If the partition key range is not already in the map, add it\n const failoverInfo = new PartitionKeyRangeFailoverInfo(failedEndPoint);\n partitionKeyRangeToLocation.set(partitionKeyRangeId, failoverInfo);\n }\n const partitionFailOver = partitionKeyRangeToLocation.get(partitionKeyRangeId);\n\n // Will return true if it was able to update to a new region\n if (\n await partitionFailOver.tryMoveNextLocation(\n nextEndPoints,\n failedEndPoint,\n diagnosticNode,\n partitionKeyRangeId,\n )\n ) {\n return true;\n }\n // All the locations have been tried. Remove the override information\n partitionKeyRangeToLocation.delete(partitionKeyRangeId);\n return false;\n }\n\n /**\n * Initiates a background loop that periodically checks for unhealthy endpoints\n * and attempts to open connections to them. If a connection is successfully\n * established, it initiates a failback to the original location for the partition key range.\n * This is useful for scenarios where a partition key range has been marked as unavailable\n * due to a circuit breaker, and we want to periodically check if the original location\n * has become healthy again.\n * The loop runs at a defined interval specified by Constants.StalePartitionUnavailabilityRefreshIntervalInMs.\n */\n private initiateCircuitBreakerFailbackLoop(): void {\n this.circuitBreakerFailbackBackgroundRefresher = startBackgroundTask(async () => {\n try {\n await this.openConnectionToUnhealthyEndpointsWithFailback();\n } catch (err) {\n console.error(\"Failed to open connection to unhealthy endpoints: \", err);\n }\n }, Constants.StalePartitionUnavailabilityRefreshIntervalInMs);\n }\n\n /**\n * Attempts to open connections to unhealthy endpoints and initiates failback if the connections are successful.\n * This method checks the partition key ranges that have failed locations and tries to re-establish connections\n * to those locations. If a connection is successfully re-established, it initiates a failback to the original\n * location for the partition key range.\n */\n private async openConnectionToUnhealthyEndpointsWithFailback(): Promise<void> {\n // If partition level circuit breaker or failover is not enabled, dispose the timer.\n const enablePartitionLevelCircuitBreaker =\n this.globalEndpointManager.enablePartitionLevelCircuitBreaker ||\n this.globalEndpointManager.enablePartitionLevelFailover;\n if (!enablePartitionLevelCircuitBreaker) {\n this.dispose();\n return;\n }\n\n for (const pkRange of this.partitionKeyRangeToLocationForReadAndWrite.keys()) {\n const partitionFailover = this.partitionKeyRangeToLocationForReadAndWrite.get(pkRange);\n if (!partitionFailover) continue;\n\n const { firstRequestFailureTime } =\n await partitionFailover.snapshotPartitionFailoverTimestamps();\n const now = new Date();\n\n if (\n now.getTime() - firstRequestFailureTime >\n Constants.AllowedPartitionUnavailabilityDurationInMs\n ) {\n // Un-deterministically marking the original failed endpoint for the PkRange back to healthy.\n // Initiate Failback to the original failed location.\n this.partitionKeyRangeToLocationForReadAndWrite.delete(pkRange);\n }\n }\n }\n}\n"]}
@@ -40,8 +40,8 @@ async function httpRequest(requestContext, diagnosticNode) {
40
40
  // If the request is a read request and partition level failover or circuit breaker is enabled,
41
41
  // set a shorter timeout to allow for quicker failover in case of partition unavailability.
42
42
  // This is to ensure that read requests can quickly failover to another partition if the current one is unavailable.
43
- if ((requestContext.connectionPolicy.enablePartitionLevelFailover ||
44
- requestContext.connectionPolicy.enablePartitionLevelCircuitBreaker) &&
43
+ if ((requestContext.globalEndpointManager.enablePartitionLevelFailover ||
44
+ requestContext.globalEndpointManager.enablePartitionLevelCircuitBreaker) &&
45
45
  requestContext.partitionKeyRangeId &&
46
46
  requestContext.resourceType === ResourceType.item &&
47
47
  isReadRequest(requestContext.operationType)) {