Skip to content

Commit bf5b86c

Browse files
emmaling27Convex, Inc.
authored andcommitted
Pass ComponentPath through action callbacks so actions in components work with funrun (#27610)
GitOrigin-RevId: 2fc374f9665390fc5a1211c862c6cde4f1e85186
1 parent d1df43b commit bf5b86c

File tree

7 files changed

+63
-59
lines changed

7 files changed

+63
-59
lines changed

crates/application/src/api.rs

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ use std::{
66
use async_trait::async_trait;
77
use bytes::Bytes;
88
use common::{
9-
components::{
10-
ComponentFunctionPath,
11-
ComponentPath,
12-
},
9+
components::ComponentFunctionPath,
1310
pause::PauseClient,
1411
runtime::Runtime,
1512
types::{
@@ -52,7 +49,6 @@ use sync_types::{
5249
AuthenticationToken,
5350
SerializedQueryJournal,
5451
Timestamp,
55-
UdfPath,
5652
};
5753
use value::{
5854
sha256::Sha256Digest,
@@ -99,7 +95,7 @@ pub trait ApplicationApi: Send + Sync {
9995
host: &str,
10096
request_id: RequestId,
10197
identity: Identity,
102-
path: UdfPath,
98+
path: ComponentFunctionPath,
10399
args: Vec<JsonValue>,
104100
caller: FunctionCaller,
105101
ts: ExecuteQueryTimestamp,
@@ -111,7 +107,7 @@ pub trait ApplicationApi: Send + Sync {
111107
host: &str,
112108
request_id: RequestId,
113109
identity: Identity,
114-
path: UdfPath,
110+
path: ComponentFunctionPath,
115111
args: Vec<JsonValue>,
116112
caller: FunctionCaller,
117113
// Identifier used to make this mutation idempotent.
@@ -123,7 +119,7 @@ pub trait ApplicationApi: Send + Sync {
123119
host: &str,
124120
request_id: RequestId,
125121
identity: Identity,
126-
path: UdfPath,
122+
path: ComponentFunctionPath,
127123
args: Vec<JsonValue>,
128124
caller: FunctionCaller,
129125
) -> anyhow::Result<Result<RedactedActionReturn, RedactedActionError>>;
@@ -133,7 +129,7 @@ pub trait ApplicationApi: Send + Sync {
133129
host: &str,
134130
request_id: RequestId,
135131
identity: Identity,
136-
udf_path: UdfPath,
132+
path: ComponentFunctionPath,
137133
args: Vec<JsonValue>,
138134
caller: FunctionCaller,
139135
) -> anyhow::Result<Result<FunctionReturn, FunctionError>>;
@@ -150,7 +146,7 @@ pub trait ApplicationApi: Send + Sync {
150146
&self,
151147
host: &str,
152148
request_id: RequestId,
153-
path: UdfPath,
149+
path: ComponentFunctionPath,
154150
http_request_metadata: HttpActionRequest,
155151
identity: Identity,
156152
caller: FunctionCaller,
@@ -209,7 +205,7 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
209205
_host: &str,
210206
request_id: RequestId,
211207
identity: Identity,
212-
udf_path: UdfPath,
208+
path: ComponentFunctionPath,
213209
args: Vec<JsonValue>,
214210
caller: FunctionCaller,
215211
ts: ExecuteQueryTimestamp,
@@ -224,10 +220,6 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
224220
ExecuteQueryTimestamp::Latest => *self.now_ts_for_reads(),
225221
ExecuteQueryTimestamp::At(ts) => ts,
226222
};
227-
let path = ComponentFunctionPath {
228-
component: ComponentPath::root(),
229-
udf_path,
230-
};
231223
self.read_only_udf_at_ts(request_id, path, args, identity, ts, journal, caller)
232224
.await
233225
}
@@ -237,7 +229,7 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
237229
_host: &str,
238230
request_id: RequestId,
239231
identity: Identity,
240-
udf_path: UdfPath,
232+
path: ComponentFunctionPath,
241233
args: Vec<JsonValue>,
242234
caller: FunctionCaller,
243235
// Identifier used to make this mutation idempotent.
@@ -248,10 +240,6 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
248240
"This method should not be used by internal callers."
249241
);
250242

251-
let path = ComponentFunctionPath {
252-
component: ComponentPath::root(),
253-
udf_path,
254-
};
255243
self.mutation_udf(
256244
request_id,
257245
path,
@@ -269,7 +257,7 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
269257
_host: &str,
270258
request_id: RequestId,
271259
identity: Identity,
272-
udf_path: UdfPath,
260+
path: ComponentFunctionPath,
273261
args: Vec<JsonValue>,
274262
caller: FunctionCaller,
275263
) -> anyhow::Result<Result<RedactedActionReturn, RedactedActionError>> {
@@ -278,10 +266,6 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
278266
"This method should not be used by internal callers."
279267
);
280268

281-
let path = ComponentFunctionPath {
282-
component: ComponentPath::root(),
283-
udf_path,
284-
};
285269
self.action_udf(request_id, path, args, identity, caller)
286270
.await
287271
}
@@ -291,14 +275,10 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
291275
_host: &str,
292276
request_id: RequestId,
293277
identity: Identity,
294-
udf_path: UdfPath,
278+
path: ComponentFunctionPath,
295279
args: Vec<JsonValue>,
296280
caller: FunctionCaller,
297281
) -> anyhow::Result<Result<FunctionReturn, FunctionError>> {
298-
let path = ComponentFunctionPath {
299-
component: ComponentPath::root(),
300-
udf_path,
301-
};
302282
self.any_udf(request_id, path, args, identity, caller).await
303283
}
304284

@@ -325,16 +305,12 @@ impl<RT: Runtime> ApplicationApi for Application<RT> {
325305
&self,
326306
_host: &str,
327307
request_id: RequestId,
328-
path: UdfPath,
308+
path: ComponentFunctionPath,
329309
http_request_metadata: HttpActionRequest,
330310
identity: Identity,
331311
caller: FunctionCaller,
332312
response_streamer: HttpActionResponseStreamer,
333313
) -> anyhow::Result<()> {
334-
let path = ComponentFunctionPath {
335-
component: ComponentPath::root(),
336-
udf_path: path,
337-
};
338314
self.http_action_udf(
339315
request_id,
340316
path,

crates/common/src/components/component_path.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,24 @@ impl From<ComponentDefinitionPath> for String {
168168
value.0
169169
}
170170
}
171+
172+
impl From<ComponentPath> for pb::common::ComponentPath {
173+
fn from(path: ComponentPath) -> Self {
174+
Self {
175+
path: path.iter().map(|name| name.to_string()).collect(),
176+
}
177+
}
178+
}
179+
180+
impl TryFrom<pb::common::ComponentPath> for ComponentPath {
181+
type Error = anyhow::Error;
182+
183+
fn try_from(value: pb::common::ComponentPath) -> Result<Self, Self::Error> {
184+
let component_names: Vec<ComponentName> = value
185+
.path
186+
.into_iter()
187+
.map(|name| name.parse::<ComponentName>())
188+
.try_collect()?;
189+
Ok(component_names.into())
190+
}
191+
}

crates/common/src/components/function_paths.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ impl ComponentFunctionPath {
5151
}
5252
}
5353

54+
impl From<UdfPath> for ComponentFunctionPath {
55+
fn from(udf_path: UdfPath) -> Self {
56+
Self {
57+
component: ComponentPath::root(),
58+
udf_path,
59+
}
60+
}
61+
}
62+
5463
#[derive(Debug, Serialize, Deserialize)]
5564
#[serde(rename_all = "camelCase")]
5665
pub struct SerializedComponentFunctionPath {

crates/isolate/src/environment/helpers/validation.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use common::{
44
CanonicalizedComponentFunctionPath,
55
ComponentFunctionPath,
66
ComponentId,
7-
ComponentName,
87
ComponentPath,
98
},
109
errors::JsError,
@@ -502,21 +501,14 @@ impl ValidatedPathAndArgs {
502501
serde_json::from_slice(&args.ok_or_else(|| anyhow::anyhow!("Missing args"))?)?;
503502
let args_value = ConvexValue::try_from(args_json)?;
504503
let args = ConvexArray::try_from(args_value)?;
504+
// TODO(CX-6865) Make required
505505
let component = component_path
506-
.map(|c| {
507-
c.path
508-
.into_iter()
509-
.map(|name| name.parse::<ComponentName>())
510-
.try_collect::<Vec<_>>()
511-
.map(ComponentPath::from)
512-
})
506+
.map(|c| c.try_into())
513507
.unwrap_or(Ok(ComponentPath::root()))?;
514508
Ok(Self {
515509
path: CanonicalizedComponentFunctionPath {
516510
component,
517-
udf_path: path
518-
.ok_or_else(|| anyhow::anyhow!("Missing udf_path"))?
519-
.parse()?,
511+
udf_path: path.context("Missing udf_path")?.parse()?,
520512
},
521513
args,
522514
npm_version: npm_version.map(|v| Version::parse(&v)).transpose()?,
@@ -536,9 +528,7 @@ impl TryFrom<ValidatedPathAndArgs> for pb::common::ValidatedPathAndArgs {
536528
) -> anyhow::Result<Self> {
537529
let args_json = JsonValue::from(args);
538530
let args = serde_json::to_vec(&args_json)?;
539-
let component_path = Some(pb::common::ComponentPath {
540-
path: path.component.iter().map(|name| name.to_string()).collect(),
541-
});
531+
let component_path = Some(path.component.into());
542532
Ok(Self {
543533
path: Some(path.udf_path.to_string()),
544534
args: Some(args),

crates/local_backend/src/http_actions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ async fn stream_http_response(
195195
.execute_http_action(
196196
&host,
197197
request_id,
198-
path,
198+
path.into(),
199199
http_request_metadata,
200200
identity,
201201
FunctionCaller::HttpEndpoint,

crates/local_backend/src/public_api.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ use axum::{
1414
response::IntoResponse,
1515
};
1616
use common::{
17+
components::{
18+
ComponentFunctionPath,
19+
ComponentPath,
20+
},
1721
http::{
1822
extract::{
1923
Json,
@@ -159,13 +163,17 @@ pub async fn public_function_post(
159163
}
160164

161165
let udf_path = parse_udf_path(&req.path)?;
166+
let component_function_path = ComponentFunctionPath {
167+
component: ComponentPath::root(),
168+
udf_path,
169+
};
162170
let udf_result = st
163171
.api
164172
.execute_any_function(
165173
host.as_str(),
166174
request_id,
167175
identity,
168-
udf_path,
176+
component_function_path,
169177
req.args.into_arg_vec(),
170178
FunctionCaller::HttpApi(client_version.clone()),
171179
)
@@ -235,7 +243,7 @@ pub async fn public_query_get(
235243
host.as_str(),
236244
request_id,
237245
identity,
238-
udf_path,
246+
udf_path.into(),
239247
args,
240248
FunctionCaller::HttpApi(client_version.clone()),
241249
ExecuteQueryTimestamp::Latest,
@@ -279,7 +287,7 @@ pub async fn public_query_post(
279287
host.as_str(),
280288
request_id,
281289
identity,
282-
udf_path,
290+
udf_path.into(),
283291
req.args.into_arg_vec(),
284292
FunctionCaller::HttpApi(client_version.clone()),
285293
ExecuteQueryTimestamp::Latest,
@@ -336,7 +344,7 @@ pub async fn public_query_batch_post(
336344
host.as_str(),
337345
request_id.clone(),
338346
identity.clone(),
339-
udf_path,
347+
udf_path.into(),
340348
req.args.into_arg_vec(),
341349
FunctionCaller::HttpApi(client_version.clone()),
342350
ExecuteQueryTimestamp::At(*ts),
@@ -384,7 +392,7 @@ pub async fn public_mutation_post(
384392
host.as_str(),
385393
request_id,
386394
identity,
387-
udf_path,
395+
udf_path.into(),
388396
req.args.into_arg_vec(),
389397
FunctionCaller::HttpApi(client_version.clone()),
390398
None,
@@ -431,7 +439,7 @@ pub async fn public_action_post(
431439
host.as_str(),
432440
request_id,
433441
identity,
434-
udf_path,
442+
udf_path.into(),
435443
req.args.into_arg_vec(),
436444
FunctionCaller::HttpApi(client_version.clone()),
437445
)

crates/sync/src/worker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ impl<RT: Runtime> SyncWorker<RT> {
458458
host.as_ref(),
459459
server_request_id,
460460
identity,
461-
udf_path,
461+
udf_path.into(),
462462
args,
463463
FunctionCaller::SyncWorker(client_version),
464464
mutation_identifier,
@@ -521,7 +521,7 @@ impl<RT: Runtime> SyncWorker<RT> {
521521
host.as_ref(),
522522
server_request_id,
523523
identity,
524-
udf_path,
524+
udf_path.into(),
525525
args,
526526
FunctionCaller::SyncWorker(client_version),
527527
)
@@ -679,7 +679,7 @@ impl<RT: Runtime> SyncWorker<RT> {
679679
host.as_ref(),
680680
RequestId::new(),
681681
identity_,
682-
query.udf_path,
682+
query.udf_path.into(),
683683
query.args,
684684
FunctionCaller::SyncWorker(client_version),
685685
ExecuteQueryTimestamp::At(new_ts),

0 commit comments

Comments
 (0)