-
Notifications
You must be signed in to change notification settings - Fork 34
WIP: Use SyncA to generate [a]sync APIs #246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
879ed99
to
e3c0356
Compare
5ae72f9
to
ef069df
Compare
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Convert more methods to async Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
items We need to avoid using `syn::UseRename` because it may cause issues after `synca` replacements Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Now `clear && cargo expand --no-default-features --features xyz 2>&1 > generated_xyz.rs` works for both xyz=sync and xyz=tokio in non-test code Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
… --features tokio` The `sync` feature build fails due to the new `Box::pin(...)` wrappers for all recursive calls Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
This way we could use .await without extra troubles Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
TODO: examples, doc tests and IT tests Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
It is not finished - somehow two lines of code lead rustc to run forever Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
This way we need more cloning but otherwise Rustc complains that it cannot resolve whether &schema::tokio::Schema is Send Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Introduce XyzExt structs for the Synca managed functionality, e.g. SchemaExt with an `impl` that contains all async methods (SchemaExt::parse_str(...) -> AvroResult<Schema>) Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
c39757c
to
184a322
Compare
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Revert async for ser_schema.rs Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
avro/src/types.rs
Outdated
Value::Decimal(ref d) => <Vec<u8>>::try_from(d) | ||
.map(|vec| Self::Array(vec.into_iter().map(|v| v.into()).collect())), | ||
Value::BigDecimal(ref bg) => { | ||
let vec1: Vec<u8> = serialize_big_decimal(bg)?; | ||
Ok(Self::Array(vec1.into_iter().map(|b| b.into()).collect())) | ||
let vec1: Vec<u8> = crate::bigdecimal::sync::serialize_big_decimal(bg)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Kriskras99 I need some help here.
This is an impl of TryFrom (i.e. cannot be async) and it needs to use an async function here (serialize_big_decimal
that uses several encode_xyz()
async functions).
Ideas how to make it work ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't. You need to add the try_from
function to a regular impl
block instead of implementing the trait. Or as you did, always use the sync version because you're writing to a Vec anyway.
This is one of the reasons I separate the reading from creating the final output in my state machine implementation.
…nabled Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
ValueExt::try_from(types::Value) -> serde_json::Value seems unused Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Woot! TODO:
|
Nice, congrats! I do question if
Anyway, really nice work! |
Good point! That reminds me: is |
I think FYI, |
I will add some async IT tests and this should expose such issues! BTW it is still not decided that the Synca approach wins over SansIO! Take your time and once you are ready we will decide what to do! In the meantime we could release a new version(s) from |
Even better would be |
As there are some people waiting for a release, might be good to start one. There's nothing important coming that should be included in the next release right? |
Nothing I am aware of! |
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
It appeared to be more complex. Parser::parse_record calls RecordFieldExt::parse() and it calls Self::resolve_default_value() and this one calls ValueExt::resolve_internal() and this calls bigdecimal::deserialize_big_decimal() and this calls decode_long() that needs to be |
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
That's a shame, I missed that branch |
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
One simple call like the one to |
Not sure whether it is bad or not but I needed to replace in several places usage of iterator combinators with |
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
This way Tokio could be just a dev-dependency and users could use another async runtime if they want! Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
This way "tokio" is not advertized. Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
This PR should be reviewed with whitespaces ignored - https://github.com/apache/avro-rs/pull/246/files?w=1
What
The purpose of this PR is to experiment with https://github.com/sgr-team/rs_synca crate to generate both async and sync/blocking APIs of the apache_avro SDK. Synca uses Rust procedural macros to generate the blocking version of the code from the manually written asynchronous version.
How it works
Synca works by "annotating" a module with async functions with
#[synca::synca]
attribute and some rules what to do when generating the sync/blocking version of the code, e.g. to remove all occurrences ofasync
and.await
and to replace someuse
s (imports) with others. In addition to removingasync/await
it also removes any usages ofBox::pin()
for theawait
ed calls which are needed to solve the issue with recursion inasync
methods.Most of the data structures, like
schema::Schema
,types::Value
,error::Error
are out of Synca's scope and are reusable from both sync and async callers. Some of their methods need to beasync
and they are extracted toXyzExt
, e.g.SchemaExt
structs which are processed by Synca. For exampleSchema::parse_str(&str) -> AvroResult<Self>
needs to be async now and that's why it is moved toSchemaExt::parse_str(&str) -> AvroResult<Schema>
. Same is valid forValue
'svalidate()
andresolve()
methods.