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

Deno hangs in Ubuntu #2124

Closed
pietvanzoen opened this issue Apr 16, 2019 · 17 comments
Closed

Deno hangs in Ubuntu #2124

pietvanzoen opened this issue Apr 16, 2019 · 17 comments
Labels
bug Something isn't working correctly
Milestone

Comments

@pietvanzoen
Copy link

I've been trying to run Deno on an Ubuntu server but I'm finding that it hangs on reading the file it's running. I initially was trying to run this on the maxmcd/deno docker image. I then tried installing/running Deno on the machine itself and ran into the same issue.

I'm a little out of my depth to debug this so any guidance would be appreciated.

Ubuntu version 18.04.2 LTS (Bionic Beaver)

> echo 'console.log("foo")' > foo.ts
> ./.deno/bin/deno --version
deno: 0.3.7
v8: 7.4.238
typescript: 3.4.1
> ./.deno/bin/deno -AD foo.ts
DEBUG RS - mkdir -p /home/piet/.cache/deno/gen
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /home/piet/.cache/deno/deps
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /home/piet/.cache/deno/deps/http
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /home/piet/.cache/deno/deps/https
DEBUG RS - set dir perm to 493
DEBUG RS - root /home/piet/.cache/deno
DEBUG RS - gen /home/piet/.cache/deno/gen
DEBUG RS - deps /home/piet/.cache/deno/deps
DEBUG RS - deps_http /home/piet/.cache/deno/deps/http
DEBUG RS - deps_https /home/piet/.cache/deno/deps/https
DEBUG RS - Deno isolate init with snapshots.
DEBUG RS - resolve_module specifier foo.ts referrer .
DEBUG RS - msg_from_js Start sync true
DEBUG JS - cwd /home/piet
DEBUG JS - args [ "foo.ts" ]
DEBUG RS - resolve_module specifier foo.ts referrer .
DEBUG RS - main_module file:///home/piet/foo.ts
DEBUG RS - fetch_module_meta_data. specifier file:///home/piet/foo.ts referrer .
DEBUG RS - resolve_module specifier file:///home/piet/foo.ts referrer .
DEBUG RS - module_name: file:///home/piet/foo.ts, filename: /home/piet/foo.ts
DEBUG RS - fetch local or reload file:///home/piet/foo.ts is_module_remote false
DEBUG RS - found local source

Then it hangs indefinitely.

Let me know what other info I can provide.

@kevinkassimo
Copy link
Contributor

@pietvanzoen Saw something similar to this in the Gitter chatroom days ago. Try search Trying to run deno in a microvm (using alpine with glibc) in the Gitter history, the follow-up comments might be helpful.

@deepchudasama
Copy link

deepchudasama commented Apr 16, 2019

Same here stuck when tried example: deno https://deno.land/std/examples/echo_server.ts --allow-net

@afinch7
Copy link
Contributor

afinch7 commented Apr 16, 2019

@jeromegn do you remember how you resolved this?
Also hang is somewhere in this async

.fetch_module_meta_data_async(&specifier, &referrer, use_cache)

@jeromegn
Copy link

@afinch7 thanks for the ping, happy to help!

There are 2 scenarios where this can happen (in my experience):

  • Only 1 cpu core available on the system (like in a VM with 1 vCPU.) Deno needs more than 1 thread to compile code.
  • Not enough entropy generated on the system (this was harder to figure out.) Check cat /proc/sys/kernel/random/entropy_avail (also our dmesg should show something like crng init done if it has enough entropy)

Low entropy prevents things like TLS handshakes which deno relies on to fetch resources. You can make entropy higher by interacting with the system normally for a while (but it might be a long process) or by adding entropy to the system via RNDADDENTROPY. You can generate bad entropy with this golang script: https://gist.github.com/jeromegn/ba3f694412979d21dafc9d625b8fcf04 or this python 3 script: linuxkit/linuxkit#3096 (comment) or by using something like haveged or rngd programs. You can also seed entropy from the last boot or the host (if you're running a VM.)

Hope this helps!

@bartlomieju
Copy link
Member

bartlomieju commented Apr 16, 2019

  • Only 1 cpu core available on the system (like in a VM with 1 vCPU.) Deno needs more than 1 thread to compile code.

@jeromegn This sounds like a bug, but still single CPU machine should be able to run more than 1 thread?

@pietvanzoen
Copy link
Author

Thanks for the insight @jeromegn! I’m running it on the cheapest DO droplet VM with 1 vcpu so I’m guessing that’s it.

Bummer but makes sense. Thanks for the responses everyone.

@ry
Copy link
Member

ry commented Apr 16, 2019

I don't understand either. Deno does use a separate thread to compile typescript but surely having 1 CPU wouldn't prevent that from happening...

@afinch7
Copy link
Contributor

afinch7 commented Apr 16, 2019

I would say it's an issue in my changes to the compile process, but I doesn't look like we even get to compile. Hence the lack of ">>>>> compile_sync START". We do get found local source, so we must get stuck right after get_source_code_aync completes. Anything here that looks problematic:

deno/cli/deno_dir.rs

Lines 166 to 223 in 97f0fe7

let mut out = match result {
Ok(out) => out,
Err(err) => {
if err.kind() == ErrorKind::NotFound {
// For NotFound, change the message to something better.
return Err(errors::new(
ErrorKind::NotFound,
format!(
"Cannot resolve module \"{}\" from \"{}\"",
specifier, referrer
),
));
} else {
return Err(err);
}
}
};
if out.source_code.starts_with(b"#!") {
out.source_code = filter_shebang(out.source_code);
}
// If TypeScript we have to also load corresponding compile js and
// source maps (called output_code and output_source_map)
if out.media_type != msg::MediaType::TypeScript || !use_cache {
return Ok(out);
}
let cache_key =
source_code_hash(&out.filename, &out.source_code, version::DENO);
let (output_code_filename, output_source_map_filename) = (
gen.join(cache_key.to_string() + ".js"),
gen.join(cache_key.to_string() + ".js.map"),
);
let result =
load_cache2(&output_code_filename, &output_source_map_filename);
match result {
Err(err) => {
if err.kind() == std::io::ErrorKind::NotFound {
// If there's no compiled JS or source map, that's ok, just
// return what we have.
Ok(out)
} else {
Err(err.into())
}
}
Ok((output_code, source_map)) => {
out.maybe_output_code = Some(output_code);
out.maybe_source_map = Some(source_map);
out.maybe_output_code_filename =
Some(output_code_filename.to_str().unwrap().to_string());
out.maybe_source_map_filename =
Some(output_source_map_filename.to_str().unwrap().to_string());
Ok(out)
}
}
}),

@methodbox
Copy link

Thanks for the insight @jeromegn! I’m running it on the cheapest DO droplet VM with 1 vcpu so I’m guessing that’s it.

Bummer but makes sense. Thanks for the responses everyone.

I can confirm this resolved my issue was well. Was trying this at work on a Hyper-V CentOS VM, ran into an issue that it doesn't support the old version of glibc on CentOS and tried on an Ubuntu VM only to have it hang.

I used the default install method via bash curl -fsSL https://deno.land/x/install/install.sh | sh.

I tried something as simple as console.log('hello world') in a test.js only to have it hang. I also cut/pasted one of the examples from deno.land; no dice.

I read this post, shutdown the VM and raised the CPU count to 2 and it worked immediately.

Note the basic CLI / REPL worked fine with a single CPU. I know this isn't Node but Node works fine with a single CPU in this same environment, just for comparison.

Saw your talk on YT @ry and decided to check this out. Hoping you can get this one resolved!

I'd offer to contribute but I'm just exploring Rust and definitely wouldn't be of any help ;)

@jeromegn
Copy link

I don't understand either. Deno does use a separate thread to compile typescript but surely having 1 CPU wouldn't prevent that from happening...

There's a chance tokio's threadpool spawns a single worker since it only detects 1 logical core. Then you run blocking operations on it (like fs-related stuff, which is allowed since it's not considered a single-threaded tokio runtime) and that just blocks everything in the event loop.

@ry
Copy link
Member

ry commented Apr 17, 2019

@jeromegn Ah! That makes sense - thank you. I will look into it.

@ry ry added the bug Something isn't working correctly label Apr 17, 2019
@ry ry added this to the v0.4 milestone Apr 17, 2019
@arcatdmz
Copy link
Contributor

arcatdmz commented May 7, 2019

This issue seems to persist in v0.4.0, replicated on a simple EC2 t2.micro instance.

[ec2-user@ip-172-31-47-111 ~]$ curl -fsSL https://deno.land/x/install/install.sh | sh
######################################################################## 100.0%
Deno was installed successfully to /home/ec2-user/.deno/bin/deno
Manually add the directory to your $HOME/.bash_profile (or similar)
  export PATH="/home/ec2-user/.deno/bin:$PATH"
Run '/home/ec2-user/.deno/bin/deno --help' to get started
[ec2-user@ip-172-31-47-111 ~]$ vi .bash_profile
[ec2-user@ip-172-31-47-111 ~]$ source .bash_profile
[ec2-user@ip-172-31-47-111 ~]$ deno version
deno: 0.4.0
v8: 7.6.53
typescript: 3.4.1
[ec2-user@ip-172-31-47-111 ~]$ deno run https://deno.land/welcome.ts
Downloading https://deno.land/welcome.ts

Then the program hangs indefinitely. With -D option, I see a similar output as @pietvanzoen. No more output after the found local source line.

@bartlomieju
Copy link
Member

bartlomieju commented May 7, 2019

There's a chance tokio's threadpool spawns a single worker since it only detects 1 logical core. Then you run blocking operations on it (like fs-related stuff, which is allowed since it's not considered a single-threaded tokio runtime) and that just blocks everything in the event loop.

AFAICT deno_dir wraps async methods in blocking() calls and uses sync approach, there is even TODO to change this behavior not to block. I can take a look at it in the evening.

@arcatdmz
Copy link
Contributor

arcatdmz commented May 7, 2019

As a side note, when I changed the AWS EC2 instance type from t2.micro (1vCPU) to t3.nano (2 vCPU), deno run worked correctly and didn't hang up.

@bartlomieju
Copy link
Member

So I've looked into this issue by manually tweaking tokio's runtime with core_threads(1) to think I have only 1 CPU available. Then indeed Deno hangs.

$ deno_dev run -r -D https://deno.land/welcome.ts
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/gen
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps/http
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps/https
DEBUG RS - set dir perm to 493
DEBUG RS - root /Users/biwanczuk/Library/Caches/deno
DEBUG RS - gen /Users/biwanczuk/Library/Caches/deno/gen
DEBUG RS - deps /Users/biwanczuk/Library/Caches/deno/deps
DEBUG RS - deps_http /Users/biwanczuk/Library/Caches/deno/deps/http
DEBUG RS - deps_https /Users/biwanczuk/Library/Caches/deno/deps/https
DEBUG RS - Deno isolate init with snapshots.
DEBUG RS - rust:shared_queue:reset
DEBUG RS - resolve_module specifier https://deno.land/welcome.ts referrer .
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:shift: num_records=0, num_shifted_off=0, head=412
DEBUG RS - resolve_module specifier https://deno.land/welcome.ts referrer .
DEBUG RS - msg_from_js Start sync true
DEBUG RS - main_module https://deno.land/welcome.ts
DEBUG RS - fetch_module_meta_data. specifier https://deno.land/welcome.ts referrer .
DEBUG RS - resolve_module specifier https://deno.land/welcome.ts referrer .
Downloading https://deno.land/welcome.ts
DEBUG RS - module_name: https://deno.land/welcome.ts, filename: /Users/biwanczuk/Library/Caches/deno/deps/https/deno.land/welcome.ts
DEBUG RS - is remote but didn't find module
DEBUG RS - resolving host="deno.land"
DEBUG RS - connecting to 54.230.228.34:443
DEBUG RS - adding I/O source: 0
DEBUG RS - scheduling Write for: 0
DEBUG RS - connected to Some(V4(54.230.228.34:443))
DEBUG RS - No cached session for DNSNameRef("deno.land")
DEBUG RS - Not resuming any session
DEBUG RS - scheduling Read for: 0
DEBUG RS - ALPN protocol is None
DEBUG RS - Using ciphersuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
DEBUG RS - Server supports tickets
DEBUG RS - ECDHE curve is ECParameters { curve_type: NamedCurve, named_group: secp256r1 }
DEBUG RS - Server cert is <skipped>
DEBUG RS - Server DNS name is DNSName("deno.land")
DEBUG RS - scheduling Read for: 0
DEBUG RS - Session saved
DEBUG RS - scheduling Read for: 0
DEBUG RS - scheduling Read for: 0
DEBUG RS - scheduling Read for: 0
DEBUG RS - flushed 45 bytes
DEBUG RS - read 475 bytes
DEBUG RS - parsed 12 headers
DEBUG RS - incoming body is content-length (37 bytes)
DEBUG RS - incoming body completed
DEBUG RS - scheduling Read for: 0
DEBUG RS - scheduling Read for: 0
DEBUG RS - scheduling Read for: 0
DEBUG RS - pooling idle connection for "https://deno.land"
DEBUG RS - set file perm to 438
DEBUG RS - >>>>> compile_sync START
DEBUG RS - Running rust part of compile_sync. specifier: https://deno.land/welcome.ts, referrer: .
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/gen
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps/http
DEBUG RS - set dir perm to 493
DEBUG RS - mkdir -p /Users/biwanczuk/Library/Caches/deno/deps/https
DEBUG RS - set dir perm to 493
DEBUG RS - root /Users/biwanczuk/Library/Caches/deno
DEBUG RS - gen /Users/biwanczuk/Library/Caches/deno/gen
DEBUG RS - deps /Users/biwanczuk/Library/Caches/deno/deps
DEBUG RS - deps_http /Users/biwanczuk/Library/Caches/deno/deps/http
DEBUG RS - deps_https /Users/biwanczuk/Library/Caches/deno/deps/https
DEBUG RS - Deno isolate init with snapshots.
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:shift: num_records=0, num_shifted_off=0, head=412
DEBUG RS - resolve_module specifier https://deno.land/welcome.ts referrer .
DEBUG RS - msg_from_js Start sync true
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:shift: num_records=0, num_shifted_off=0, head=412
DEBUG RS - msg_from_js CompilerConfig sync true
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:shift: num_records=0, num_shifted_off=0, head=412
DEBUG RS - msg_from_js WorkerGetMessage sync false
DEBUG RS - Cmd id for response sender insert: 1
DEBUG RS - Start worker stream handler!
DEBUG RS - Sent message to worker
DEBUG RS - op_worker_get_message
DEBUG RS - scheduling Read for: 0
DEBUG RS - rust:shared_queue:push: num_records=1, num_shifted_off=0, head=540
DEBUG RS - Sending warning alert CloseNotify
DEBUG RS - scheduling Read for: 0
DEBUG RS - dropping I/O source: 0
DEBUG RS - rust:shared_queue:reset
DEBUG RS - rust:shared_queue:shift: num_records=0, num_shifted_off=0, head=412
DEBUG RS - fetch_module_meta_data. specifier https://deno.land/welcome.ts referrer .
DEBUG RS - resolve_module specifier https://deno.land/welcome.ts referrer .
Downloading https://deno.land/welcome.ts
DEBUG RS - module_name: https://deno.land/welcome.ts, filename: /Users/biwanczuk/Library/Caches/deno/deps/https/deno.land/welcome.ts
DEBUG RS - is remote but didn't find module

I followed code path and it seems problem is not with blocking calls. Additionally tokio has default limit of 100 concurrent blocking calls.

Strangely it looks like file is downloaded twice... @ry is this intended behavior?

@bartlomieju
Copy link
Member

I just tested this bug with #2380 landed, even if there's only 1 core available Deno no longer hangs.

@ry I think we can close this issue now

@ry ry closed this as completed May 29, 2019
@horihiro
Copy link

I'm creating deno docker image for Azure 'Web App for Containers'.
https://github.com/horihiro/docker_deno_webapp4containers

Before deno 0.6.0, deno couldn't work on single core tier.
After updating to 0.7.0, deno works well!

Many thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly
Projects
None yet
Development

No branches or pull requests

11 participants