Skip to content

Commit dce2cbd

Browse files
nipunn1313Convex, Inc.
authored andcommitted
Count sync worker mutation channel full as rate limited (#28450)
If mutation channel is full, then client has sent too many mutations. Classify as 429 rather than 503 at this layer. GitOrigin-RevId: 4333d2248957056effb8d26230e6fabd1fecfb80
1 parent aebdf0b commit dce2cbd

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

crates/application/src/application_function_runner/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,11 @@ impl Limiter {
424424
log_function_wait_timeout(self.env, self.udf_type);
425425
anyhow::bail!(ErrorMetadata::rate_limited(
426426
"TooManyConcurrentRequests",
427-
"Too many concurrent requests, backoff and try again.",
427+
format!(
428+
"Too many concurrent requests. Your backend is limited to {} concurrent {}s. To get more resources, upgrade to Convex Pro. If you are already on Convex Pro, please contact support.",
429+
self.total_permits,
430+
self.udf_type.to_lowercase_string(),
431+
),
428432
));
429433
},
430434
}

crates/errors/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ impl ErrorMetadata {
153153
/// The short_msg should be a CapitalCamelCased describing the error (eg
154154
/// TooManyTeams). The msg should be a descriptive message targeted
155155
/// toward the developer.
156+
///
157+
/// In the user facing `msg`, be very clear about what is actionable here.
158+
/// Some rate limits require paying for more resources, while others are
159+
/// indicative of incorrect user behavior (eg > 1000 concurrent mutations
160+
/// over a single websocket).
156161
pub fn rate_limited(
157162
short_msg: impl Into<Cow<'static, str>>,
158163
msg: impl Into<Cow<'static, str>>,

crates/sync/src/worker.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,9 +521,13 @@ impl<RT: Runtime> SyncWorker<RT> {
521521
.boxed();
522522
self.mutation_sender.try_send(future).map_err(|err| {
523523
if err.is_full() {
524-
anyhow::anyhow!(ErrorMetadata::overloaded(
524+
anyhow::anyhow!(ErrorMetadata::rate_limited(
525525
"TooManyConcurrentMutations",
526-
"Too many concurrent mutations, backoff and try again.",
526+
format!(
527+
"Too many concurrent mutations. Only up to \
528+
{OPERATION_QUEUE_BUFFER_SIZE} pending mutations allowed on a \
529+
single websocket."
530+
),
527531
))
528532
} else {
529533
anyhow::anyhow!("Failed to send to mutation channel: {err}")

0 commit comments

Comments
 (0)