Skip to content
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

Update library implementation for rustler v0.22 (contd.) #37

Merged
merged 3 commits into from
Jun 17, 2021

Conversation

jeroenvisser101
Copy link
Contributor

Continuation of #35, fixes issues related to a botched upgrade, and completes the upgrade.

This also adds GitHub actions, which should replace Travis.

@@ -126,20 +125,15 @@ enum ParserType {
XmlDocument,
}

fn parse<'a>(parser_type: ParserType, env: Env<'a>, args: &[Term<'a>]) -> NifResult<Term<'a>> {
fn parse<'a>(parser_type: ParserType, env: Env<'a>, document: Binary) -> NifResult<Term<'a>> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems to work fine, tests pass, but it drops the previous panic, for what I guess will be a rustler specific error?

Copy link
Owner

@mischov mischov Jun 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain to me the change in signature?

Is that a change in Rustler v0.22? Can you point me to the appropriate documentation there if it is?

Copy link
Contributor Author

@jeroenvisser101 jeroenvisser101 Jun 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was changed, but to be honest, the documentation is either hidden or not there, as the only way I figured out about this is by looking at others who had already updated.

The error without it is the one I mentioned before:

error[E0277]: the trait bound `&[rustler::Term<'a>]: Decoder<'_>` is not satisfied
   --> src/lib.rs:177:1
    |
177 | #[rustler::nif(schedule = "DirtyCpu")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Decoder<'_>` is not implemented for `&[rustler::Term<'a>]`
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `&[rustler::Term<'a>]: Decoder<'_>` is not satisfied
   --> src/lib.rs:182:1
    |
182 | #[rustler::nif(schedule = "DirtyCpu")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Decoder<'_>` is not implemented for `&[rustler::Term<'a>]`
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

I'm very new to Rust, and don't really have a clue as to why this change is needed. I'm not sure if there's a way to keep Term and get it to work with Decoder, but if there is then maybe we can do that instead. No preference on my end here, just trying to get it to compile (which it does 😄)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That something called "args", the first element of which was the document that needed parsing, is getting replaced by the document that is being parsed makes me think there is going to be a mismatch there.

I will need time to review Rustler's changes and figure out what's going on and how best to address that issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and some other files in that PR) are the only references that change this as well, but I couldn't really find it in the changelog, but I may have missed it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I confirmed that your approach (replacing the slice of terms that was args with the actual arg, in this case document) is the correct one.

That was the approach suggested here by @evnu.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very new to Rust, and don't really have a clue as to why this change is needed.

The rustler changelog actually mentions this, but it is possibly too opaque.

NIFs can be derived from regular functions, if the arguments implement Decoder and the return type implements Encoder:

Before the upcoming rustler, args was a slice of Term which needed to be decoded. Each entry in args corresponds with one argument passed into the function. Now with rustler v0.22, the arguments are spelled out explicitly, just like in a regular function.

Do you have a suggestion to make this more obvious for the users of rustler? Where would you expect that information?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evnu maybe some examples of the before and after could help. I figured this out by comparing libraries that had already upgraded from those that had not. Maybe UPGRADING.md file?

Maybe the changelog entry was fine, but like I said, I'm not familiar with rustler or rust, so someone else may have read Encoder/Decoder and knew immediately that those sliced params (?) would be replaced with it.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evnu I saw the example in the changelog under the "NIFs can be derived from regular functions..." note but I wasn't sure if it related to this because the signatures were so different:

add<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error>

vs

fn add(a: i64, b: i64) -> i64

An example that just showed args being replaced by each individual arg would have been clearer.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe UPGRADING.md file?

That's a good idea, thanks!

@jeroenvisser101
Copy link
Contributor Author

This should fix #36, but the implementation there is a bit more advanced. If you want me to add caching and move formatting check to a different job, I'm happy to do so :)

@mischov
Copy link
Owner

mischov commented Jun 16, 2021

Sorry, but could I get you to remove the Github Actions bits. That's work that should be in a separate branch off master with its own PR.

I am in the process of adding the Github Actions stuff myself and I'd like to do it incrementally (remove travis, add workflow similar to what travis last tested, upgrade the versions tested). Appreciate you trying to save me work, though.

@jeroenvisser101
Copy link
Contributor Author

For sure, no worries, I rebased and dropped the commit with Github actions. If you want me to add it in a separate PR anyway, let me know, happy to help

@mischov mischov mentioned this pull request Jun 17, 2021

fn on_load<'a>(_env: Env<'a>, _load_info: Term<'a>) -> bool {
fn load(_env: Env, _load_info: Term) -> bool {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious what prompted the change from on_load to load?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this was honestly only to align with what rustler.new would generate if ran today, it's not a required change

@mischov
Copy link
Owner

mischov commented Jun 17, 2021

With the exception of that load vs on_load stuff (and I'm mostly just curious what prompted you to make that change) everything looks good to me.

I do want to take a moment and thank you for figuring all this stuff out- from what I've seen not a lot of libraries have moved to the Rustler v0.22 stuff yet so it looks like you were blazing a bit of a trail there.

@jeroenvisser101
Copy link
Contributor Author

I do want to take a moment and thank you for figuring all this stuff out- from what I've seen not a lot of libraries have moved to the Rustler v0.22 stuff yet so it looks like you were blazing a bit of a trail there.

Thanks 👍 I've only found 3 or so other packages that have updated, and those were very helpful to get a feel for what was changed.

I made 2 additional changes, one is to include the priv folder, which was required to get it to build in CI/docker: rusterlium/rustler#326. I think this fix wasn't in this RC yet, so we should be able to revert it later on, I think

@mischov
Copy link
Owner

mischov commented Jun 17, 2021

@jeroenvisser101 Do you think this is ready to merge or are you still testing?

@jeroenvisser101
Copy link
Contributor Author

I think it's ready, but the change from dylib to cdylib may not have been needed, although it is now the default. We're planning to deploy this to prod later today, but we've tested our use of meeseeks and all is working correctly.

@mischov
Copy link
Owner

mischov commented Jun 17, 2021

I think the change to cdylib is ok.

The Rust docs say this about cdylib:

This is used when compiling a dynamic library to be loaded from another language.

That sounds a lot like our use case, though I'm not sure if it comes with any downsides.

@mischov mischov marked this pull request as ready for review June 17, 2021 15:55
@mischov mischov merged commit 6a6f10e into mischov:master Jun 17, 2021
@mischov
Copy link
Owner

mischov commented Jun 17, 2021

Let me know if any problems pop up once you deploy to prod.

Thank you again.

@jeroenvisser101
Copy link
Contributor Author

We deployed it and it worked fine :)

Thanks for the help and your time 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants