@wildix/xbees-conversations-utils 1.1.79 → 1.1.80

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.
@@ -121,6 +121,43 @@ class RedisCooldown {
121
121
  });
122
122
  }
123
123
  }
124
+ static async setRemainingMsWithValue(cooldownKey, valueKey, value, cooldownMs, context, options) {
125
+ if (value.length === 0 || cooldownMs <= 0) {
126
+ return;
127
+ }
128
+ const { redis, logger } = context;
129
+ const cooldownRedisKey = RedisCooldown.resolveRedisKey(cooldownKey, options);
130
+ const valueRedisKey = RedisCooldown.resolveRedisKey(valueKey, options);
131
+ try {
132
+ await redis.eval(`
133
+ local cooldown_key = KEYS[1]
134
+ local value_key = KEYS[2]
135
+ local value = ARGV[1]
136
+ local new_ttl = tonumber(ARGV[2])
137
+ local current_ttl = redis.call('PTTL', cooldown_key)
138
+ local final_ttl = new_ttl
139
+
140
+ if current_ttl == -2 then
141
+ redis.call('SET', cooldown_key, '1', 'PX', new_ttl)
142
+ elseif current_ttl == -1 or current_ttl < new_ttl then
143
+ redis.call('PEXPIRE', cooldown_key, new_ttl)
144
+ else
145
+ final_ttl = current_ttl
146
+ end
147
+
148
+ redis.call('SET', value_key, value, 'PX', final_ttl)
149
+ return final_ttl
150
+ `, 2, cooldownRedisKey, valueRedisKey, value, cooldownMs.toString());
151
+ }
152
+ catch (error) {
153
+ logger.warn('Failed to write stream rate-limit cooldown and metadata to Redis', {
154
+ cooldownKey,
155
+ valueKey,
156
+ cooldownMs,
157
+ error,
158
+ });
159
+ }
160
+ }
124
161
  static async clear(cooldownKey, context, options) {
125
162
  const { redis, logger } = context;
126
163
  try {
@@ -106,9 +106,11 @@ async function executeWithRateLimitHandling(execute, operation, context, options
106
106
  const retryAfterMs = calculateRateLimitDelayMs(rateLimitError, maxDelayMs);
107
107
  if (enableCooldown) {
108
108
  const rateLimitSnapshot = toRateLimitSnapshot(rateLimitError);
109
- await RedisCooldown_1.RedisCooldown.setRemainingMs(operation, retryAfterMs, { redis, logger });
110
109
  if (rateLimitSnapshot) {
111
- await RedisCooldown_1.RedisCooldown.setValueWithRemainingMs(getRateLimitMetadataKey(operation), (0, rateLimitSnapshot_1.serializeRateLimitSnapshot)(rateLimitSnapshot), retryAfterMs, { redis, logger });
110
+ await RedisCooldown_1.RedisCooldown.setRemainingMsWithValue(operation, getRateLimitMetadataKey(operation), (0, rateLimitSnapshot_1.serializeRateLimitSnapshot)(rateLimitSnapshot), retryAfterMs, { redis, logger });
111
+ }
112
+ else {
113
+ await RedisCooldown_1.RedisCooldown.setRemainingMs(operation, retryAfterMs, { redis, logger });
112
114
  }
113
115
  }
114
116
  if (attempt < maxAttempts && retryAfterMs <= maxRetryableDelayMs) {
@@ -118,6 +118,43 @@ export class RedisCooldown {
118
118
  });
119
119
  }
120
120
  }
121
+ static async setRemainingMsWithValue(cooldownKey, valueKey, value, cooldownMs, context, options) {
122
+ if (value.length === 0 || cooldownMs <= 0) {
123
+ return;
124
+ }
125
+ const { redis, logger } = context;
126
+ const cooldownRedisKey = RedisCooldown.resolveRedisKey(cooldownKey, options);
127
+ const valueRedisKey = RedisCooldown.resolveRedisKey(valueKey, options);
128
+ try {
129
+ await redis.eval(`
130
+ local cooldown_key = KEYS[1]
131
+ local value_key = KEYS[2]
132
+ local value = ARGV[1]
133
+ local new_ttl = tonumber(ARGV[2])
134
+ local current_ttl = redis.call('PTTL', cooldown_key)
135
+ local final_ttl = new_ttl
136
+
137
+ if current_ttl == -2 then
138
+ redis.call('SET', cooldown_key, '1', 'PX', new_ttl)
139
+ elseif current_ttl == -1 or current_ttl < new_ttl then
140
+ redis.call('PEXPIRE', cooldown_key, new_ttl)
141
+ else
142
+ final_ttl = current_ttl
143
+ end
144
+
145
+ redis.call('SET', value_key, value, 'PX', final_ttl)
146
+ return final_ttl
147
+ `, 2, cooldownRedisKey, valueRedisKey, value, cooldownMs.toString());
148
+ }
149
+ catch (error) {
150
+ logger.warn('Failed to write stream rate-limit cooldown and metadata to Redis', {
151
+ cooldownKey,
152
+ valueKey,
153
+ cooldownMs,
154
+ error,
155
+ });
156
+ }
157
+ }
121
158
  static async clear(cooldownKey, context, options) {
122
159
  const { redis, logger } = context;
123
160
  try {
@@ -103,9 +103,11 @@ export async function executeWithRateLimitHandling(execute, operation, context,
103
103
  const retryAfterMs = calculateRateLimitDelayMs(rateLimitError, maxDelayMs);
104
104
  if (enableCooldown) {
105
105
  const rateLimitSnapshot = toRateLimitSnapshot(rateLimitError);
106
- await RedisCooldown.setRemainingMs(operation, retryAfterMs, { redis, logger });
107
106
  if (rateLimitSnapshot) {
108
- await RedisCooldown.setValueWithRemainingMs(getRateLimitMetadataKey(operation), serializeRateLimitSnapshot(rateLimitSnapshot), retryAfterMs, { redis, logger });
107
+ await RedisCooldown.setRemainingMsWithValue(operation, getRateLimitMetadataKey(operation), serializeRateLimitSnapshot(rateLimitSnapshot), retryAfterMs, { redis, logger });
108
+ }
109
+ else {
110
+ await RedisCooldown.setRemainingMs(operation, retryAfterMs, { redis, logger });
109
111
  }
110
112
  }
111
113
  if (attempt < maxAttempts && retryAfterMs <= maxRetryableDelayMs) {
@@ -6,5 +6,6 @@ export declare class RedisCooldown {
6
6
  static setRemainingMsExact(cooldownKey: string, cooldownMs: number, context: RedisContext & LoggerContext, options?: RedisCooldownOptions): Promise<void>;
7
7
  static getValue(cooldownKey: string, context: RedisContext & LoggerContext, options?: RedisCooldownOptions): Promise<string | undefined>;
8
8
  static setValueWithRemainingMs(cooldownKey: string, value: string, cooldownMs: number, context: RedisContext & LoggerContext, options?: RedisCooldownOptions): Promise<void>;
9
+ static setRemainingMsWithValue(cooldownKey: string, valueKey: string, value: string, cooldownMs: number, context: RedisContext & LoggerContext, options?: RedisCooldownOptions): Promise<void>;
9
10
  static clear(cooldownKey: string, context: RedisContext & LoggerContext, options?: RedisCooldownOptions): Promise<void>;
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wildix/xbees-conversations-utils",
3
- "version": "1.1.79",
3
+ "version": "1.1.80",
4
4
  "description": "",
5
5
  "main": "./dist-cjs/index.js",
6
6
  "module": "./dist-es/index.js",