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

example: prototype op crate #3031

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"cli",
"core",
"op_hello_js",
"tools/hyper_hello",
"deno_typescript",
"js",
Expand Down
19 changes: 19 additions & 0 deletions op_hello/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This is an imagined crate directory structure for Deno ops.

[package]
name = "op_hello"
version = "0.1.0"
authors = ["Ryan Dahl <ry@tinyclouds.org>"]
edition = "2018"

# Note: I am explicitly attempting to not have a build.rs file. I think it might
# be unnecessary for each op crate to implement their own. Then again, it might
# be unavoidable... Let's try without first.

[dependencies]
deno = "0.19.0"
# deno_std is needed because hello_test.ts depends on the "testing/mod.ts" file
# inside of deno_std.
# TODO deno_std is not yet published as crate
deno_std = "0.19.0"

12 changes: 12 additions & 0 deletions op_hello/src/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const OP_HELLO: number = Deno.ops.add("hello");

// https://www.typescriptlang.org/docs/handbook/namespaces.html#splitting-across-files
namespace Deno {
/**
* The typedoc here ideally would be presevered automatically in
* lib.deno_runtime.d.ts
*/
export function hello() {
Deno.core.send(OP_HELLO);
}
}
34 changes: 34 additions & 0 deletions op_hello/src/hello_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// We need some way to import test modules.
// Attempt one:
//
// import { test } from "../../js/test_util.ts";
//
// Here it is referencing files across crate boundaries, which will break
// 'cargo package' and means the crate is not useable outside the deno tree.
// This might be okay for a first pass, but it's not the best solution.
//
// Attempt two:
// 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.
import { test } from "crate://deno_std/testing/mod.ts";

// If we don't do the //src reorg that I've proposed in #3022, then we might be
// able to have a very elegant URL some day using the deno crate.
//
// import { test } from "crate://deno/std/testing/mod.ts";

import "./hello.ts";

test("hello test", () => {
Deno.hello();
});

test("hello test2", () => {
Deno.hello();
});
41 changes: 41 additions & 0 deletions op_hello/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
extern crate deno;
extern crate deno_std;
use deno::*;

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

// Explicitly link the deno_std crate so it can be used in hello_test.ts
// Its usage looks like this:
//
// import { test } from "crate://deno_std/testing/mod.ts";
//
// In the future it might make sense to automate this function away, but I think
// it would be prudent to make the crate URL resolution as obvious as
// possible.
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")
}

fn op_hello(_control_buf: &[u8], _zero_copy_buf: Option<PinnedBuf>) -> CoreOp {
println!("Hello world");
CoreOp::Sync(Box::new([]))
}

#[test]
fn rust_test() {
match op_hello() {
CoreOp::Sync(buf) => {
assert_eq!(buf.len(), 0);
}
CoreOp::Async(_) => unreachable!(),
}
}

#[test]
fn js_test() {
// This should execute src/hello_test.ts
deno_test();
}
23 changes: 23 additions & 0 deletions op_hello_js/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This is an imagined crate directory structure for Deno ops.
# Same as op_hello but done with JS and not TS.

[package]
name = "op_hello_js"
version = "0.1.0"
authors = ["Ryan Dahl <ry@tinyclouds.org>"]
edition = "2018"

[lib]
path = "lib.rs"

[dependencies]
deno = { path = "../core", version = "0.19.0" }

[[example]]
name = "op_hello_example"
path = "examples/hello.rs"

# tokio is only used for op_hello_example
[dev_dependencies]
futures = "0.1.29"
tokio = "0.1.18"
1 change: 1 addition & 0 deletions op_hello_js/examples/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello();
41 changes: 41 additions & 0 deletions op_hello_js/examples/hello.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// To run this benchmark:
///
/// > DENO_BUILD_MODE=release ./tools/build.py && \
/// ./target/release/deno_core_http_bench --multi-thread
extern crate deno;
extern crate futures;
extern crate tokio;

use deno::*;
use futures::future::lazy;
use tokio::prelude::*;


fn main() {
let main_future = lazy(move || {
// TODO currently isolate.execute() must be run inside tokio, hence the
// lazy(). It would be nice to not have that contraint. Probably requires
// using v8::MicrotasksPolicy::kExplicit

let js_source = include_str!("hello.js");

let mut isolate = deno::Isolate::new(StartupData::None, false);
let r = op_hello_js::init(&mut isolate);
eprintln!("result r {:?}", r);
let r = isolate.execute("hello.js", js_source);
eprintln!("result r {:?}", r);

isolate.then(|r| {
js_check(r);
Ok(())
})
});

tokio::runtime::current_thread::run(main_future);
}

fn js_check(r: Result<(), ErrBox>) {
if let Err(e) = r {
panic!(e.to_string());
}
}
6 changes: 6 additions & 0 deletions op_hello_js/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// TODO In the future maybe we can extract the op id in the top-level and use a
// constant. But currently it's causing problems with snapshotting.

function hello() {
Deno.core.send(Deno.core.ops()["hello"]);
}
4 changes: 4 additions & 0 deletions op_hello_js/hello_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// As opposed to the TypeScript op_hello example, here we want to not rely on
// deno_std, as it uses TypeScript. So here don't use a test runner.
import { hello } from "./hello.js";
hello();
27 changes: 27 additions & 0 deletions op_hello_js/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
extern crate deno;
use deno::*;

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

fn op_hello(_control_buf: &[u8], _zero_copy_buf: Option<PinnedBuf>) -> CoreOp {
println!("Hello world");
CoreOp::Sync(Box::new([]))
}

#[test]
fn js_test() {
isolate.execute("hello_test.js")
}

#[test]
fn rust_test() {
if let CoreOp::Sync(buf) = op_hello() {
assert_eq!(buf.len(), 0);
} else {
unreachable!();
}
}