Skip to content

Commit f027067

Browse files
fix!: metagen papercuts (#950)
<!-- Pull requests are squashed and merged using: - their title as the commit message - their description as the commit body Having a good title and description is important for the users to get readable changelog. --> <!-- 1. Explain WHAT the change is about --> Solves [MET-761](https://linear.app/metatypedev/issue/MET-761/metagen-papercuts): - Make generator naming consistent with the client_xx and fdk_xx format. Prefer shortened names of languages like the extension name of source files. - Reuse a typegraph serialization across multiple generation runs in a single cli invocation. It currently re-serializes a typegraph if it's referenced twice. - Explicit return types on QueryGraph methods for Typescript - Support for non-record queries for Gql transport. Currently, one's forced to name the query/mutation section which gets reflected in the response name <!-- 3. Explain HOW users should update their code --> #### Migration notes --- - [x] The change comes with new or modified tests - [ ] Hard-to-understand functions have explanatory comments - [x] End-user documentation is updated to reflect the change <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit Based on the comprehensive summary, here are the high-level release notes: - **Generator Naming** - Simplified generator names across the project - Updated from `fdk_typescript` → `fdk_ts` - Updated from `fdk_python` → `fdk_py` - Updated from `fdk_rust` → `fdk_rs` - **Type Management** - Transitioned from `Box<Typegraph>` to `Arc<Typegraph>` for improved memory management - Enhanced type flexibility in query and mutation methods - Added support for single and multiple node operations - **New Features** - Added identity and identity update functions across TypeScript, Python, and Rust clients - Improved caching mechanisms for typegraphs - Enhanced GraphQL transport layer with more flexible input handling - **Documentation** - Updated configuration examples and references to reflect new generator names <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent ab10235 commit f027067

File tree

57 files changed

+1009
-360
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1009
-360
lines changed

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ members = [
44
"src/common",
55
"src/meta-cli",
66
"src/metagen",
7-
"src/metagen/src/fdk_rust/static",
7+
"src/metagen/src/fdk_rs/static",
88
"src/mt_deno",
99
"src/typegate/engine",
1010
"src/typegate/standalone",

docs/metatype.dev/docs/guides/external-functions/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ metagen:
104104
targets:
105105
# named targets to configure a bunch of generators together
106106
metagen_deno:
107-
- generator: fdk_typescript # generator to use
107+
- generator: fdk_ts # generator to use
108108
# path to generate to
109109
path: ./metagen/ts/
110110
# point to the typegraph location
@@ -142,7 +142,7 @@ Within `fdk.ts` and the types and helpers, all the types from your typegraph sho
142142

143143
</details>
144144

145-
Note, this also include typescript function types for specific typegraph functions. By default, the `fdk_typescript` generator will only include stub function types for those defined on the `DenoRuntime` but this is [configurable](/docs/reference/metagen#fdk_typescript).
145+
Note, this also include typescript function types for specific typegraph functions. By default, the `fdk_ts` generator will only include stub function types for those defined on the `DenoRuntime` but this is [configurable](/docs/reference/metagen#fdk_ts).
146146

147147
We can then use these types in the following manner. Add the following snippet into `metagen/ts/remix.ts`.
148148

docs/metatype.dev/docs/guides/wasm-functions/index.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ Note that the `WasmRuntime` constructor mentions a non-existent wasm file on dis
3939

4040
## Metagen
4141

42-
We can now tackle the boilerplate. Metagen bundles the [`fdk_rust`](/docs/reference/metagen#fdk_rust) generator which can generate all the glue code along with Rust types that correspond to our typegraph types. Let's configure a metagen target in our configuration file to get just that done.
42+
We can now tackle the boilerplate. Metagen bundles the [`fdk_rs`](/docs/reference/metagen#fdk_rs) generator which can generate all the glue code along with Rust types that correspond to our typegraph types. Let's configure a metagen target in our configuration file to get just that done.
4343

4444
```yaml
4545
metagen:
4646
targets:
4747
metagen_rs:
4848
# this is the generator we're interested in
49-
- generator: fdk_rust
49+
- generator: fdk_rs
5050
# the location where to put the generated files
5151
path: ./metagen/rs/
5252
# the path to our typegraph
@@ -69,7 +69,7 @@ This should give us the following files:
6969
└──  fdk.rs
7070
```
7171

72-
By default, the `fdk_rust` generator outputs all the necessary files required to build our wasm file. This includes the `Cargo.toml` manifest for our Rust crate.
72+
By default, the `fdk_rs` generator outputs all the necessary files required to build our wasm file. This includes the `Cargo.toml` manifest for our Rust crate.
7373

7474
<CodeBlock language="toml">
7575
{
@@ -78,7 +78,7 @@ By default, the `fdk_rust` generator outputs all the necessary files required to
7878
}
7979
</CodeBlock>
8080

81-
`fdk_rust` will not overwrite a `Cargo.toml` file discovered at generation path so you can add other dependencies if need be.
81+
`fdk_rs` will not overwrite a `Cargo.toml` file discovered at generation path so you can add other dependencies if need be.
8282

8383
The `fdk.rs` file contains all the glue code including the typegraph types.
8484

docs/metatype.dev/docs/reference/metagen/index.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ metagen:
3636
targets:
3737
main:
3838
# generator to use
39-
- generator: fdk_rust
39+
- generator: fdk_rs
4040
# path to generate to
4141
path: ./bff/
4242
# typegraph path to use
4343
typegraph_path: ./typegraphs/svc-bff.ts
4444
# we can have multiple generators per target
45-
- generator: fdk_rust
45+
- generator: fdk_rs
4646
path: ./telemetry/
4747
typegraph_path: ./typegraphs/svc-telemetry.ts
4848
# generators might have custom keys
@@ -118,7 +118,7 @@ This generator supports:
118118

119119
Refer to the [client reference](/docs/reference/typegraph/client/) for usage guidelines and examples.
120120

121-
### `fdk_typescript`
121+
### `fdk_ts`
122122

123123
This generator supports:
124124

@@ -163,14 +163,14 @@ It supports the following extra configuration keys.
163163
| ------------------ | ---------- | ---------- | ------------------------------------------ |
164164
| `stubbed_runtimes` | `string[]` | `["deno"]` | Runtimes for which to generate stub types. |
165165

166-
### `fdk_python`
166+
### `fdk_py`
167167

168168
This generator supports:
169169

170170
- Python classes that map to typegraph types
171171
- Decorators for custom functions implementors that require adherance to typegraph function types.
172172
- By default, all functions from the `PythonRuntime` get stub types.
173-
- TODO: `stubbed_runtimes` for `fdk_python`
173+
- TODO: `stubbed_runtimes` for `fdk_py`
174174
- TODO: types for interacting with the typegate from within custom functions.
175175

176176
If the referenced module for the custom function is not found, the generator will also output stub implementation (in addition to the types) at the given type. It will not replace our code on a second run.
@@ -202,7 +202,7 @@ Custom function:
202202
/>
203203
</details>
204204

205-
### `fdk_rust`
205+
### `fdk_rs`
206206

207207
This generator generates types, serializers and bindings needed to implement custom functions in Rust. Rust implementations will need to be compiled to wasm components to be executed on the metatype platform and the generator assumes such usage.
208208

examples/metatype.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,14 @@ typegraphs:
173173
metagen:
174174
targets:
175175
metagen_deno:
176-
- generator: fdk_typescript
176+
- generator: fdk_ts
177177
path: ./typegraphs/metagen/ts/
178178
typegraph_path: ./typegraphs/metagen-deno.ts
179179
metagen_py:
180-
- generator: fdk_python
180+
- generator: fdk_py
181181
path: ./typegraphs/metagen/py/
182182
typegraph_path: ./typegraphs/metagen-py.ts
183183
metagen_rs:
184-
- generator: fdk_rust
184+
- generator: fdk_rs
185185
path: ./typegraphs/metagen/rs/
186186
typegraph_path: ./typegraphs/metagen-rs.ts

examples/typegraphs/metagen-sdk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def metagen_sdk(g: Graph):
4545
"targets": {
4646
"main": [
4747
{
48-
"generator": "fdk_typescript",
48+
"generator": "fdk_ts",
4949
"typegraph_path": __file__,
5050
"path": "funcs/",
5151
},

examples/typegraphs/metagen-sdk.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ if (false) {
5252
targets: {
5353
main: [
5454
{
55-
generator: "fdk_typescript",
55+
generator: "fdk_ts",
5656
typegraph_path: myPath,
5757
path: "funcs/",
5858
},

src/common/src/node.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use anyhow::{Context, Result};
55
use indoc::indoc;
66
use reqwest::{Client, IntoUrl, RequestBuilder, Url};
77
use serde::Serialize;
8-
use std::{collections::HashMap, time::Duration};
8+
use std::{collections::HashMap, sync::Arc, time::Duration};
99

1010
use crate::{
1111
graphql::{self, Query},
@@ -129,7 +129,7 @@ impl Node {
129129
Ok(())
130130
}
131131

132-
pub async fn typegraph(&self, name: &str) -> Result<Option<Box<Typegraph>>, Error> {
132+
pub async fn typegraph(&self, name: &str) -> Result<Option<Arc<Typegraph>>, Error> {
133133
let res = self
134134
.post("/typegate")
135135
.map_err(Error::Other)?
@@ -157,7 +157,7 @@ impl Node {
157157
return Ok(None);
158158
};
159159
serde_json::from_str::<Typegraph>(&res.serialized)
160-
.map(|tg| Some(Box::new(tg)))
160+
.map(|tg| Some(Arc::new(tg)))
161161
.map_err(|err| Error::Other(anyhow::anyhow!(err)))
162162
}
163163
}

src/meta-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ git2 = { workspace = true, features = [
7878
], default-features = false }
7979

8080
# codecs
81-
serde.workspace = true
81+
serde = { workspace = true, features = ["rc"] }
8282
serde_json = { workspace = true, features = ["preserve_order"] }
8383
flate2.workspace = true
8484
tar.workspace = true

src/meta-cli/src/cli/fdk_template.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ impl Action for CreateFdkTemplate {
3838
.context("failed to create target directory")?;
3939

4040
let template = match self.template {
41-
Template::Rust => metagen::FDK_RUST_DEFAULT_TEMPLATE,
42-
Template::Python => metagen::FDK_PYTHON_DEFAULT_TEMPLATE,
43-
Template::Typescript => metagen::FDK_TYPESCRIPT_DEFAULT_TEMPLATE,
41+
Template::Rust => metagen::FDK_RS_DEFAULT_TEMPLATE,
42+
Template::Python => metagen::FDK_PY_DEFAULT_TEMPLATE,
43+
Template::Typescript => metagen::FDK_TS_DEFAULT_TEMPLATE,
4444
};
4545

4646
for (file_name, content) in template.iter() {

src/meta-cli/src/cli/gen.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{config::Config, deploy::actors::console::ConsoleActor};
1313
use actix::Actor;
1414
use clap::Parser;
1515
use common::typegraph::Typegraph;
16+
use dashmap::DashMap;
1617
use futures_concurrency::future::FutureGroup;
1718
use metagen::*;
1819

@@ -59,6 +60,7 @@ impl Action for Gen {
5960
config: config.clone(),
6061
dir,
6162
typegate: Arc::new(node),
63+
typegraph_cache: DashMap::new(),
6264
};
6365

6466
if !mgen_conf.targets.contains_key(&self.gen_target) {
@@ -100,11 +102,28 @@ impl Action for Gen {
100102
}
101103
}
102104

103-
#[derive(Clone, Debug)]
105+
#[derive(Debug)]
104106
struct MetagenCtx {
105107
config: Arc<Config>,
106108
typegate: Arc<common::node::Node>,
107109
dir: PathBuf,
110+
typegraph_cache: DashMap<String, Arc<Typegraph>>,
111+
}
112+
113+
impl MetagenCtx {
114+
async fn get_cached_typegraph_or(
115+
&self,
116+
key: &str,
117+
fetch: impl Future<Output = Result<Arc<Typegraph>>>,
118+
) -> Result<Arc<Typegraph>> {
119+
if let Some(cached) = self.typegraph_cache.get(key) {
120+
Ok(cached.value().clone())
121+
} else {
122+
let result = fetch.await?;
123+
self.typegraph_cache.insert(key.to_string(), result.clone());
124+
Ok(result)
125+
}
126+
}
108127
}
109128

110129
async fn load_fdk_template(
@@ -143,22 +162,37 @@ impl InputResolver for MetagenCtx {
143162
async fn resolve(&self, order: GeneratorInputOrder) -> Result<GeneratorInputResolved> {
144163
Ok(match order {
145164
GeneratorInputOrder::TypegraphFromTypegate { name } => {
146-
GeneratorInputResolved::TypegraphFromTypegate {
147-
raw: self
148-
.typegate
149-
.typegraph(&name)
150-
.await?
151-
.with_context(|| format!("no typegraph found under {name:?}"))?,
152-
}
165+
let raw = self
166+
.get_cached_typegraph_or(&name, async {
167+
self.typegate
168+
.typegraph(&name)
169+
.await?
170+
.with_context(|| format!("no typegraph found under {name:?}"))
171+
})
172+
.await?;
173+
174+
GeneratorInputResolved::TypegraphFromTypegate { raw }
153175
}
154176
GeneratorInputOrder::TypegraphFromPath { path, name } => {
155177
let config = self.config.clone();
178+
let key = format!(
179+
"{}{}",
180+
path.to_string_lossy(),
181+
name.clone().unwrap_or_default()
182+
);
156183
let path = self
157184
.dir
158185
.join(path)
159186
.canonicalize()
160187
.wrap_err("unable to canonicalize typegraph path, make sure it exists")?;
161-
let raw = load_tg_at(config, path, name.as_deref(), &self.dir).await?;
188+
189+
let raw = self
190+
.get_cached_typegraph_or(
191+
&key,
192+
load_tg_at(config, path, name.as_deref(), &self.dir),
193+
)
194+
.await?;
195+
162196
GeneratorInputResolved::TypegraphFromTypegate { raw }
163197
}
164198
GeneratorInputOrder::LoadFdkTemplate {
@@ -178,7 +212,7 @@ async fn load_tg_at(
178212
path: PathBuf,
179213
name: Option<&str>,
180214
dir: &Path,
181-
) -> anyhow::Result<Box<Typegraph>> {
215+
) -> anyhow::Result<Arc<Typegraph>> {
182216
let console = ConsoleActor::new(Arc::clone(&config)).start();
183217

184218
let config_dir: Arc<Path> = config.dir().unwrap_or_log().into();

src/meta-cli/src/cli/serialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ impl Action for Serialize {
130130

131131
pub trait SerializeReportExt {
132132
#[allow(clippy::vec_box)]
133-
fn into_typegraphs(self) -> Result<Vec<Box<Typegraph>>>;
133+
fn into_typegraphs(self) -> Result<Vec<Arc<Typegraph>>>;
134134
}
135135

136136
impl SerializeReportExt for Report<SerializeAction> {
137-
fn into_typegraphs(self) -> Result<Vec<Box<Typegraph>>> {
137+
fn into_typegraphs(self) -> Result<Vec<Arc<Typegraph>>> {
138138
let mut res = vec![];
139139
for entry in self.entries.into_iter() {
140140
match entry.status {

src/meta-cli/src/deploy/actors/task/serialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub struct SerializeError {
8080
pub errors: Vec<String>,
8181
}
8282

83-
impl OutputData for Box<Typegraph> {
83+
impl OutputData for Arc<Typegraph> {
8484
fn get_typegraph_name(&self) -> String {
8585
self.name().unwrap()
8686
}
@@ -104,7 +104,7 @@ impl OutputData for SerializeError {
104104
}
105105

106106
impl TaskAction for SerializeAction {
107-
type SuccessData = Box<Typegraph>;
107+
type SuccessData = Arc<Typegraph>;
108108
type FailureData = SerializeError;
109109
type Options = SerializeOptions;
110110
type Generator = SerializeActionGenerator;

src/metagen/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ serde_json.workspace = true
2323
heck.workspace = true
2424

2525
# ds
26+
dashmap.workspace = true
2627
indexmap.workspace = true
2728
regex.workspace = true
2829
tera = { workspace = true, default-features = false }

0 commit comments

Comments
 (0)