-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
Adds CodeCache handler #402
Conversation
b4ef3fb
to
10ded40
Compare
@@ -0,0 +1,47 @@ | |||
import("//build_extra/rust/rust.gni") | |||
|
|||
# TODO(ry) "flatbuffer.gni" should be "flatbuffers.gni" we should be consistant |
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.
Consistent
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.
Done.
"--rust", | ||
|
||
#"--gen-mutable", | ||
#"--keep-prefix", |
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.
Why are these commented out?
src/deno_dir.rs
Outdated
// https://github.com/ry/deno/blob/golang/deno_dir.go#L99-L111 | ||
pub fn setup() -> std::io::Result<()> { | ||
// Only setup once. | ||
if unsafe { ROOT != None } { |
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.
Why unsafe?
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.
Because it's a static global.
src/binding.cc
Outdated
v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len); | ||
return view; | ||
if (buf.alloc_ptr == nullptr) { | ||
// If alloc_ptr isn't set, we memcpy. |
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.
This is alright.
src/deno_dir.rs
Outdated
// In the Go code this was called SrcDir. Renaming to Deps. | ||
// Example: /Users/rld/.deno/deps/ | ||
Deps, | ||
// In the Go code this was called CacheDir. Renaming to GEN. |
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.
Gen or GEN ?
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.
Fixed.
src/deno_dir.rs
Outdated
} | ||
pub use self::Dirname::*; | ||
|
||
pub fn path(dirname: Dirname) -> &'static Path { |
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.
Using Path now, that's a step forward :)
src/deno_dir.rs
Outdated
if unsafe { ROOT != None } { | ||
return Ok(()); | ||
} | ||
let home_dir = std::env::home_dir().expect("Could not get home directory."); |
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.
Would rather convert home_dir
Path/PathBuf here and get rid of the unsafe block below.
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.
It is a PathBuf here already https://doc.rust-lang.org/std/env/fn.home_dir.html
The unsafe is for the static global assignment.
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.
Ah, I didn't know this was considered unsafe
src/deno_dir.rs
Outdated
|
||
// https://github.com/ry/deno/blob/golang/deno_dir.go#L32-L35 | ||
pub fn cache_path(filename: &str, source_code: &str) -> PathBuf { | ||
let cache_key = source_code_hash(filename, source_code); |
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.
So if a file's dependencies change, there's no need to recompile?
(Just asking, I don't know)
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.
That's right. In the compiled code the requires will reference the original module specifier, not the specifier of the compiled file.
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.
What I mean is, some file might need to be recompiled if it's dependencies change. Like in C++ when a header changes.
I'n typescript this may be the case too but maybe not, idk. Did you consider this?
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.
@piscisaureus Yeah, I don't think that happens... but let's see if we find any examples as we flesh out the tests.
pub fn read_file_sync(path: &Path) -> std::io::Result<String> { | ||
File::open(path).and_then(|mut f| { | ||
let mut contents = String::new(); | ||
f.read_to_string(&mut contents)?; |
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.
This is not generally safe, because a file's contents are not necessarily valid utf-8.
We'll make it read to a buffer later? Otherwise consider renaming the function to read_text_file_sync
.
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.
Oh - I thought Strings were like std::string
. Sigh. Will change...
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.
This gonna stay as it is?
src/handlers.rs
Outdated
fn string_from_ptr(ptr: *const c_char) -> String { | ||
let cstr = unsafe { CStr::from_ptr(ptr as *const i8) }; | ||
String::from(cstr.to_str().unwrap()) | ||
// Help. Is there a way to do this without macros? |
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.
I don't think so -- an &str expects to store a reference to it's underlying String, but *const c_char
isn't and can't be used as such (a String is not just a pointer, but also stores length
, capacity
, refcount
etc.).
This is the reason you have to construct a new String here.
If you make str_from_ptr
a function then the String goes out of scope at the end of the function.
(you could also return both, but I suspect that might also defeat the purpose of this convenience wrapper).
Mostly LGTM now. Strangely I didn manage to build this PR, but now that I'm trying again, I get this error (freshly checked out, cleaned, third_party reset and cleaned etc). C:\Users\BertBelder\d\deno>python tools\build.py |
Hmm, it seems that git creates the wrong kind of symlinks now that third_party has become a separate repo. |
Are the global mutables necessary? Can't all of this go into a struct that owns those globals and methods? |
@robbym I agree it shouldn't be global. I've reworked it to be a standalone struct. |
8c27dcc
to
5bf369b
Compare
@piscisaureus PTAL. I've done some refactoring and added more tests.
This does indeed give us 10x startup on a warm run:
|
148cc38
to
6e47cfc
Compare
The test fails for me: outputrunning 9 tests test deno_dir::test_resolve_module ... ok test deno_dir::test_cache_path ... ok test deno_dir::test_source_code_hash ... ok test deno_dir::test_code_cache ... ok test deno_dir::test_src_file_to_url ... ok test test_parse_core_args_1 ... ok test test_parse_core_args_2 ... ok test test_c_to_rust ... ok test deno_dir::test_code_fetch ... FAILEDfailures: ---- deno_dir::test_code_fetch stdout ---- failures: test result: FAILED. 8 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out The issue is that |
@piscisaureus I believe I've fixed that using your add_root! macro. |
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.
Your last patch makes the tests pass on windows.
The startup time numbers are really encouraging. Nice work!
I wonder what the "fix logger" commit fixes - I never had any trouble with it?
I had a few comments. See what you wanna do with them, lgtm otherwise.
src/deno_dir.rs
Outdated
if cache_path.exists() { | ||
Ok(()) | ||
} else { | ||
let mut file = File::create(cache_path)?; |
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.
This is a race condition w.r.t to exists() -- probably should create the file in exclusive mode.
I also worry what might happen is there are two processes and one reads the cache file while the other is in the midst of writing it.
Not suggesting you fix it as part of this PR, but it'll have to be done some time.
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.
I added a todo comment.
pub fn read_file_sync(path: &Path) -> std::io::Result<String> { | ||
File::open(path).and_then(|mut f| { | ||
let mut contents = String::new(); | ||
f.read_to_string(&mut contents)?; |
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.
This gonna stay as it is?
let errmsg = format!("{}", err); | ||
reply_error(d, cmd_id, &errmsg); | ||
} | ||
// null response indicates success. |
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.
Implicit null response is a foot gun. Probably better to explicitly say reply_null() if a handler succeeds without a return value.
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.
Agree. I think this whole interface is going to change dramatically soon. This is just a first pass. I'll leave it as is now.
ptr: 0 as *const binding::DenoC, | ||
dir: deno_dir::DenoDir::new(None).unwrap(), | ||
}); | ||
let deno: &'a mut Deno = Box::leak(deno_box); |
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.
Jeez... I can see how this makes for some sleepless nights.
Why is Deno made mutable here if it gets cast to *const one line below?
(Not saying it's wrong, I just don't understand this very well.)
A little comment on what's going on here would be in order too (as in -- mention that C-Deno needs a reference to Rust-Deno. And why this leak is necessary (is it really btw?).
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.
It gets returned as mut (but my confidence that this is optimal code is low)
This is a utility function for CodeCache and other handlers.
They finally tagged v2.0.0 so there's no reason to use our own fork any longer.
…enoland#443) A little cleanup and showcase how to wire up custom module types in the `fs_module_loader.rs` example. Ref denoland#402
Depends on #396