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

WIP a prototype crate design for ops #3025

Closed
wants to merge 12 commits into from
Closed

WIP a prototype crate design for ops #3025

wants to merge 12 commits into from

Conversation

ry
Copy link
Member

@ry ry commented Sep 26, 2019

cc @afinch7 @bartlomieju

browse files at https://github.com/ry/deno/tree/op_hello/op_hello

super minimal MVP would be pure JS, https://github.com/ry/deno/tree/op_hello/op_hello_js

This isn't working, just trying to imagine what the ideal structure would look like.

// we invent a new URL for referencing files in other crates.
// this is magic and not browser compatible.. Browser compatibility for
// ops is not so important.
import { test } from "crate://deno_std@0.19.0/testing/mod.ts";
Copy link
Member Author

Choose a reason for hiding this comment

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

@afinch7 is this along the lines of what you were thinking?

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks good. It's very nice that all the relevant info is encoded into standard elements of the url structure. No need to design fancy parsing.

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

I like the ideas outlined in this PR - they do not require too much magic, but we still need to figure out ops registration in JS

//
// This is quite nice. But the version of deno_std already specified in
// Cargo.toml. I think we shouldn't repeat it.
import { test } from "crate://deno_std/testing/mod.ts";
Copy link
Member

Choose a reason for hiding this comment

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

// we invent a new URL for referencing files in other crates.
// this is magic and not browser compatible.. Browser compatibility for
// ops is not so important.
//
// import { test } from "crate://deno_std@0.19.0/testing/mod.ts";
//
// This is quite nice. But the version of deno_std already specified in
// Cargo.toml. I think we shouldn't repeat it.

This is least magical that we can hope for and it's an URL after all. I like this idea very much 👍

@@ -0,0 +1,12 @@
const OP_HELLO: number = Deno.ops.add("hello");
Copy link
Member

Choose a reason for hiding this comment

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

So this is cool and I'd really like to use it that way, however due to quirks related to shared_queue I was unable to make this solution work - see comments

Copy link
Member

@bartlomieju bartlomieju Sep 26, 2019

Choose a reason for hiding this comment

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

Actually I'm gonna try to implement it once more, I'll get back to you.

EDIT: Okay so the problem is that during snapshotting we're just loading JS files. The "state" used for snapshot is bare minimum and it does not have any ops registered - that means that during snapshotting Deno.ops.add("hello") wouldn't find counterpart of this op in Rust and won't be able to retrieve id.

Opinions @ry?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, ok - well let's not worry about the exact spelling of this - we can always adjust it in the future. How about this API:

export function hello() {
  Deno.core.send(Deno.ops["hello"]);
}

https://github.com/ry/deno/blob/op_hello/op_hello_js/hello.js

Copy link
Member

Choose a reason for hiding this comment

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

@ry that will work (given that we "synchronize" ops on runtime initialization), however presented solution brings back @afinch7's concerns about performance hit caused by object lookup on each op call. Still we can start with this API and then figure out how to make it fast

Copy link
Member Author

@ry ry Sep 26, 2019

Choose a reason for hiding this comment

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

I'm quite sure we're not at the level where a hash look up like that would effect our performance. I hope we are some day...

Copy link
Member

Choose a reason for hiding this comment

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

Should I update #3002 to use this API?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you're in agreement, yea

Copy link
Member

Choose a reason for hiding this comment

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

@ry PR updated

Copy link
Contributor

Choose a reason for hiding this comment

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

In hindsight I think that hash lookup is fine, and I think my testing was flawed when I originally tested performance with a similar api.

@bartlomieju
Copy link
Member

@ry could we game out example with "json" dispatch in this PR as well? It's gonna be most often used method to write ops so it'd be nice to see how we can fit it in this model

@ry
Copy link
Member Author

ry commented Sep 26, 2019

@bartlomieju I'd rather land an example crate that uses core only first. I think it keeps us honest about the interfaces. There are bigger problems of how to get ThreadSafeState into the ops - but it can be solved maybe by introducing a special type of init function which receives a deno_cli::Worker instead of deno::Isolate. We want to still enable some typescript hater to build a "deno.js" style project. So let's make this work in the simple case first in core, then later build on that structure to deliver cli op crates.

That is to say, I'm not sure how exactly json dispatch in this crate format should look, but I'm sure we can find some trick to make it not terrible : )

@bartlomieju
Copy link
Member

There are bigger problems of how to get ThreadSafeState into the ops - but it can be solved maybe by introducing a special type of init function which receives a deno_cli::Worker instead of deno::Isolate.

I figured it out in #3004, please see cli/worker.rs. That solution can be generalized to provide any additional arguments to ops as long as trait boundaries are satisfied.

We want to still enable some typescript hater to build a "deno.js" style project. So let's make this work in the simple case first in core, then later build on that structure to deliver cli op crates.

That's fine for me, I can tinker on my own


pub fn init(&mut isolate: Isolate) -> Result<(), ErrBox> {
isolate.register_op("hello", op_hello); // register_op defined by #3002
isolate.execute("hello.js")?;
Copy link
Member

Choose a reason for hiding this comment

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

I think it should be:

isolate.execute("hello.js", include_str!("hello.js"));`

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, probably. I'm a bit concerned about double counting the source code if we do snapshots...

isolate.register_crate_url("deno_std", deno_std::get_file);

// TODO The ability to run typescript doesn't exist in deno core.
isolate.run("src/hello.ts")
Copy link
Member

Choose a reason for hiding this comment

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

What about ES modules? AFAIK Isolate has only low level API for them and all the complexity is hidden in modules.rs.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes we should support that too.

@ry
Copy link
Member Author

ry commented Oct 2, 2019

Closing because this isn't intended to be landed. Just an example branch.

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