Skip to content

Commit f4076d8

Browse files
nipunn1313Convex, Inc.
authored andcommitted
Report duration and memory for queries and mutations (#41795)
Previously only for actions. GitOrigin-RevId: 0f2c3672748bc2af12c5ec554b82fa1845aec921
1 parent 78b6cb9 commit f4076d8

File tree

9 files changed

+80
-78
lines changed

9 files changed

+80
-78
lines changed

crates/application/src/function_log.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,10 @@ impl<RT: Runtime> FunctionExecutionLog<RT> {
638638
if was_cached {
639639
CallType::CachedQuery
640640
} else {
641-
CallType::UncachedQuery
641+
CallType::UncachedQuery {
642+
duration: execution_time,
643+
memory_in_mb: outcome.memory_in_mb,
644+
}
642645
},
643646
outcome.result.is_ok(),
644647
usage_stats,
@@ -794,6 +797,8 @@ impl<RT: Runtime> FunctionExecutionLog<RT> {
794797
context.execution_id,
795798
context.request_id.clone(),
796799
CallType::Mutation {
800+
duration: execution_time,
801+
memory_in_mb: outcome.memory_in_mb,
797802
occ_info: occ_info.clone(),
798803
},
799804
outcome.result.is_ok(),

crates/database/src/tests/usage_tracking.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,11 @@ async fn vector_insert_counts_usage_for_backfilling_indexes(rt: TestRuntime) ->
117117
test_udf_identifier(),
118118
ExecutionId::new(),
119119
RequestId::new(),
120-
CallType::Mutation { occ_info: None },
120+
CallType::Mutation {
121+
occ_info: None,
122+
duration: Duration::ZERO,
123+
memory_in_mb: 0,
124+
},
121125
true,
122126
tx_usage.gather_user_stats(),
123127
)
@@ -301,7 +305,11 @@ async fn test_usage_tracking_basic_insert_and_get(rt: TestRuntime) -> anyhow::Re
301305
test_udf_identifier(),
302306
ExecutionId::new(),
303307
RequestId::new(),
304-
CallType::Mutation { occ_info: None },
308+
CallType::Mutation {
309+
occ_info: None,
310+
duration: Duration::ZERO,
311+
memory_in_mb: 0,
312+
},
305313
true,
306314
tx_usage.gather_user_stats(),
307315
)
@@ -330,7 +338,11 @@ async fn test_usage_tracking_basic_insert_and_get(rt: TestRuntime) -> anyhow::Re
330338
test_udf_identifier(),
331339
ExecutionId::new(),
332340
RequestId::new(),
333-
CallType::Mutation { occ_info: None },
341+
CallType::Mutation {
342+
occ_info: None,
343+
duration: Duration::ZERO,
344+
memory_in_mb: 0,
345+
},
334346
true,
335347
tx_usage.gather_user_stats(),
336348
)
@@ -376,7 +388,11 @@ async fn test_usage_tracking_insert_with_index(rt: TestRuntime) -> anyhow::Resul
376388
test_udf_identifier(),
377389
ExecutionId::new(),
378390
RequestId::new(),
379-
CallType::Mutation { occ_info: None },
391+
CallType::Mutation {
392+
occ_info: None,
393+
duration: Duration::ZERO,
394+
memory_in_mb: 0,
395+
},
380396
true,
381397
tx_usage.gather_user_stats(),
382398
)
@@ -404,7 +420,11 @@ async fn test_usage_tracking_insert_with_index(rt: TestRuntime) -> anyhow::Resul
404420
test_udf_identifier(),
405421
ExecutionId::new(),
406422
RequestId::new(),
407-
CallType::Mutation { occ_info: None },
423+
CallType::Mutation {
424+
occ_info: None,
425+
duration: Duration::ZERO,
426+
memory_in_mb: 0,
427+
},
408428
true,
409429
tx_usage.gather_user_stats(),
410430
)
@@ -435,7 +455,11 @@ async fn test_usage_tracking_insert_with_index(rt: TestRuntime) -> anyhow::Resul
435455
test_udf_identifier(),
436456
ExecutionId::new(),
437457
RequestId::new(),
438-
CallType::Mutation { occ_info: None },
458+
CallType::Mutation {
459+
occ_info: None,
460+
duration: Duration::ZERO,
461+
memory_in_mb: 0,
462+
},
439463
true,
440464
tx_usage.gather_user_stats(),
441465
)

crates/isolate/src/environment/udf/async_syscall.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ impl<RT: Runtime> AsyncSyscallProvider<RT> for DatabaseUdfEnvironment<RT> {
587587
udf_server_version: _,
588588
unix_timestamp: _,
589589
rng_seed: _,
590+
memory_in_mb: _,
590591
} = outcome;
591592

592593
log_run_udf(

crates/isolate/src/environment/udf/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use common::{
44
ResolvedComponentFunctionPath,
55
},
66
execution_context::ExecutionContext,
7+
knobs::ISOLATE_MAX_USER_HEAP_SIZE,
78
};
89
use futures::{
910
future::BoxFuture,
@@ -450,6 +451,9 @@ impl<RT: Runtime> DatabaseUdfEnvironment<RT> {
450451
));
451452
},
452453
)?;
454+
let memory_in_mb = (*ISOLATE_MAX_USER_HEAP_SIZE / (1 << 20))
455+
.try_into()
456+
.unwrap();
453457
let outcome = match self.udf_type {
454458
UdfType::Query => FunctionOutcome::Query(UdfOutcome {
455459
path: self.path.for_logging(),
@@ -468,6 +472,7 @@ impl<RT: Runtime> DatabaseUdfEnvironment<RT> {
468472
},
469473
syscall_trace: self.syscall_trace,
470474
udf_server_version: self.udf_server_version,
475+
memory_in_mb,
471476
}),
472477
// TODO: Add num_writes and write_bandwidth to UdfOutcome,
473478
// and use them in log_mutation.
@@ -488,6 +493,7 @@ impl<RT: Runtime> DatabaseUdfEnvironment<RT> {
488493
},
489494
syscall_trace: self.syscall_trace,
490495
udf_server_version: self.udf_server_version,
496+
memory_in_mb,
491497
}),
492498
_ => anyhow::bail!("UdfEnvironment should only run queries and mutations"),
493499
};

crates/isolate/src/isolate2/runner.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use common::{
1919
},
2020
errors::JsError,
2121
execution_context::ExecutionContext,
22+
knobs::ISOLATE_MAX_USER_HEAP_SIZE,
2223
log_lines::{
2324
LogLevel,
2425
LogLine,
@@ -553,6 +554,7 @@ async fn run_request<RT: Runtime>(
553554
result: Err(js_error),
554555
syscall_trace: SyscallTrace::new(),
555556
udf_server_version,
557+
memory_in_mb: 0,
556558
};
557559
return Ok(outcome);
558560
}
@@ -696,6 +698,9 @@ async fn run_request<RT: Runtime>(
696698
result: result.map(JsonPackedValue::pack),
697699
syscall_trace: provider.syscall_trace,
698700
udf_server_version,
701+
memory_in_mb: (*ISOLATE_MAX_USER_HEAP_SIZE / (1 << 20))
702+
.try_into()
703+
.unwrap(),
699704
};
700705
Ok(outcome)
701706
}

crates/pb/protos/outcome.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ message UdfOutcome {
3131
SyscallTrace syscall_trace = 8;
3232

3333
optional bool observed_identity = 10;
34+
uint64 memory_in_mb = 11;
3435
}
3536

3637
message ActionOutcome {

crates/udf/src/udf_outcome.rs

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ use pb::{
2121
},
2222
outcome::UdfOutcome as UdfOutcomeProto,
2323
};
24-
#[cfg(any(test, feature = "testing"))]
25-
use proptest::prelude::Arbitrary;
26-
#[cfg(any(test, feature = "testing"))]
27-
use proptest::prelude::Strategy;
2824
use rand::Rng;
2925
use value::{
3026
heap_size::HeapSize,
@@ -37,7 +33,10 @@ use crate::{
3733
};
3834

3935
#[derive(Debug, Clone)]
40-
#[cfg_attr(any(test, feature = "testing"), derive(PartialEq))]
36+
#[cfg_attr(
37+
any(test, feature = "testing"),
38+
derive(proptest_derive::Arbitrary, PartialEq)
39+
)]
4140
pub struct UdfOutcome {
4241
pub path: CanonicalizedComponentFunctionPath,
4342
pub arguments: ConvexArray,
@@ -59,63 +58,9 @@ pub struct UdfOutcome {
5958

6059
pub syscall_trace: SyscallTrace,
6160

61+
#[cfg_attr(any(test, feature = "testing"), proptest(value = "None"))]
6262
pub udf_server_version: Option<semver::Version>,
63-
}
64-
65-
#[cfg(any(test, feature = "testing"))]
66-
impl Arbitrary for UdfOutcome {
67-
type Parameters = ();
68-
69-
type Strategy = impl Strategy<Value = UdfOutcome>;
70-
71-
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
72-
use proptest::prelude::*;
73-
(
74-
any::<CanonicalizedComponentFunctionPath>(),
75-
any::<ConvexArray>(),
76-
any::<InertIdentity>(),
77-
any::<[u8; 32]>(),
78-
any::<bool>(),
79-
any::<UnixTimestamp>(),
80-
any::<bool>(),
81-
any::<bool>(),
82-
any::<LogLines>(),
83-
any::<QueryJournal>(),
84-
any::<Result<JsonPackedValue, JsError>>(),
85-
any::<SyscallTrace>(),
86-
)
87-
.prop_map(
88-
|(
89-
path,
90-
arguments,
91-
identity,
92-
rng_seed,
93-
observed_rng,
94-
unix_timestamp,
95-
observed_time,
96-
observed_identity,
97-
log_lines,
98-
journal,
99-
result,
100-
syscall_trace,
101-
)| Self {
102-
path,
103-
arguments,
104-
identity,
105-
rng_seed,
106-
observed_rng,
107-
unix_timestamp,
108-
observed_time,
109-
observed_identity,
110-
log_lines,
111-
journal,
112-
result,
113-
syscall_trace,
114-
// Ok to not generate semver::Version because it is not serialized anyway
115-
udf_server_version: None,
116-
},
117-
)
118-
}
63+
pub memory_in_mb: u64,
11964
}
12065

12166
impl HeapSize for UdfOutcome {
@@ -148,6 +93,7 @@ impl TryFrom<UdfOutcome> for UdfOutcomeProto {
14893
result,
14994
syscall_trace,
15095
udf_server_version: _,
96+
memory_in_mb,
15197
}: UdfOutcome,
15298
) -> anyhow::Result<Self> {
15399
let result = match result {
@@ -166,6 +112,7 @@ impl TryFrom<UdfOutcome> for UdfOutcomeProto {
166112
}),
167113
syscall_trace: Some(syscall_trace.try_into()?),
168114
observed_identity: Some(observed_identity),
115+
memory_in_mb,
169116
})
170117
}
171118
}
@@ -195,6 +142,7 @@ impl UdfOutcome {
195142
syscall_trace: SyscallTrace::new(),
196143
udf_server_version,
197144
observed_identity: false,
145+
memory_in_mb: 0,
198146
})
199147
}
200148

@@ -209,6 +157,7 @@ impl UdfOutcome {
209157
result,
210158
syscall_trace,
211159
observed_identity,
160+
memory_in_mb,
212161
}: UdfOutcomeProto,
213162
path_and_args: ValidatedPathAndArgs,
214163
identity: InertIdentity,
@@ -249,6 +198,7 @@ impl UdfOutcome {
249198
udf_server_version,
250199
// TODO(lee): Remove the default once we've pushed all services.
251200
observed_identity: observed_identity.unwrap_or(true),
201+
memory_in_mb,
252202
})
253203
}
254204
}

crates/udf/src/validation.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ pub struct ValidatedUdfOutcome {
806806

807807
pub udf_server_version: Option<semver::Version>,
808808
pub mutation_queue_length: Option<usize>,
809+
pub memory_in_mb: u64,
809810
}
810811

811812
impl HeapSize for ValidatedUdfOutcome {
@@ -845,6 +846,7 @@ impl ValidatedUdfOutcome {
845846
syscall_trace: SyscallTrace::new(),
846847
udf_server_version,
847848
mutation_queue_length: None,
849+
memory_in_mb: 0,
848850
})
849851
}
850852

@@ -868,6 +870,7 @@ impl ValidatedUdfOutcome {
868870
syscall_trace: outcome.syscall_trace,
869871
udf_server_version: outcome.udf_server_version,
870872
mutation_queue_length,
873+
memory_in_mb: outcome.memory_in_mb,
871874
};
872875

873876
// TODO(CX-6318) Don't pack json value until it's been validated.

crates/usage_tracking/src/lib.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,13 @@ pub enum CallType {
112112
},
113113
Export,
114114
CachedQuery,
115-
UncachedQuery,
115+
UncachedQuery {
116+
duration: Duration,
117+
memory_in_mb: u64,
118+
},
116119
Mutation {
120+
duration: Duration,
121+
memory_in_mb: u64,
117122
occ_info: Option<OccInfo>,
118123
},
119124
Import,
@@ -127,7 +132,7 @@ impl CallType {
127132
Self::Action { .. } => "action",
128133
Self::Export => "export",
129134
Self::CachedQuery => "cached_query",
130-
Self::UncachedQuery => "uncached_query",
135+
Self::UncachedQuery { .. } => "uncached_query",
131136
Self::Mutation { .. } => "mutation",
132137
Self::HttpAction { .. } => "http_action",
133138
Self::Import => "import",
@@ -145,7 +150,7 @@ impl CallType {
145150

146151
fn occ_document_id(&self) -> Option<String> {
147152
match self {
148-
Self::Mutation { occ_info } => {
153+
Self::Mutation { occ_info, .. } => {
149154
occ_info.as_ref().and_then(|info| info.document_id.clone())
150155
},
151156
_ => None,
@@ -179,19 +184,21 @@ impl CallType {
179184

180185
fn memory_megabytes(&self) -> u64 {
181186
match self {
182-
CallType::Action { memory_in_mb, .. } | CallType::HttpAction { memory_in_mb, .. } => {
183-
*memory_in_mb
184-
},
187+
CallType::UncachedQuery { memory_in_mb, .. }
188+
| CallType::Mutation { memory_in_mb, .. }
189+
| CallType::Action { memory_in_mb, .. }
190+
| CallType::HttpAction { memory_in_mb, .. } => *memory_in_mb,
185191
_ => 0,
186192
}
187193
}
188194

189195
fn duration_millis(&self) -> u64 {
190196
match self {
191-
CallType::Action { duration, .. } | CallType::HttpAction { duration, .. } => {
192-
u64::try_from(duration.as_millis())
193-
.expect("Action was running for over 584 billion years??")
194-
},
197+
CallType::UncachedQuery { duration, .. }
198+
| CallType::Mutation { duration, .. }
199+
| CallType::Action { duration, .. }
200+
| CallType::HttpAction { duration, .. } => u64::try_from(duration.as_millis())
201+
.expect("Function was running for over 584 billion years??"),
195202
_ => 0,
196203
}
197204
}

0 commit comments

Comments
 (0)