I have a fairly small program (around 5k lines of code), with some heavy dependencies such as Tokio, Actix, Serde and Tokio-Tungstenite. I can't get it to compile outside of Docker because it eats all my RAM + Swap (I have 16Gb.) However, when I compile in Docker with a two steps compilation process, it takes only 1Gb.
My Cargo.toml
```[dependencies]
serde = {version = "1.0.116", features = ["derive"]}
serde_json = "1.0.58"
reqwest = {version = "0.10.8"}
futures = { version = "0.3.6", default-features = false, features = ["async-await"]}
tokio = {version = "0.2.22", features = ["rt-threaded", "macros", "tcp"]}
itertools = "0.9.0"
dotenv = "0.15.0"
futures-util = { version = "0.3.6", features = ["sink", "std"] }
tokio-tungstenite = {version = "0.10.1", features = ["connect", "tls"]}
tokio-tls = "0.3.1"
hmac = "0.9"
sha2 = "0.9.1"
mongodb = "1.1.1"
bson = "1.1.0"
actix-web = "3.1.0"
actix-rt = "1.1.1"
rustc-serialize = "0.3.24"
chrono = { version = "0.4.19", features = ["serde"] }
[profile.release]
lto = true
codegen-units = 1
opt-level = 3
My Dockerfile:
FROM rust:latest AS build_base
RUN USER=root cargo new --bin myapp
WORKDIR /myapp
COPY Cargo.toml .
RUN cargo build --release
RUN rm -f src/.rs
COPY ./src ./src
RUN rm ./target/release/deps/myapp
RUN cargo build --release
FROM rust:latest
WORKDIR /myapp
COPY --from=build_base /myapp/target/release/myapp /myapp/myapp
RUN touch .env
EXPOSE 8000
CMD ["./myapp"]
### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->
`rustc --version --verbose`:
rustc 1.49.0-nightly (a1dfd2490 2020-10-05)
binary: rustc
commit-hash: a1dfd2490a6cb456b92e469fa550dc217e20ad6d
commit-date: 2020-10-05
host: x86_64-unknown-linux-gnu
release: 1.49.0-nightly
LLVM version: 11.0
```
What's the Rust version in the Docker container?
@jonas-schievink It is rust:latest, so I would assume 1.46
Does it still use 16 GB if you use that Rust version outside of the container?
@sakex: Is it possible for you to upload your repository? If not, does the high RAM usage occur when building dependencies, or when building your repository?
@jonas-schievink It is
rust:latest, so I would assume 1.46
How recently have you docker pulled? Docker does not update images automatically.
@jonas-schievink, @Aaron1011, @sfackler I actually tried to compile with 1.44.0. It almost didn't use any RAM and it took way less time than I'm used to.
@Aaron1011 I can make give you access to my repo but I'd rather not share it. The code is quite complicated/messy actually.
@sfackler Given my discovery, I will not try to docker pull unless you really need some insights.
Are there any ways I could assist you in finding the regression?
I tried with 1.45.0 and 1.46.0. The bug was introduced in 1.46.0.
Is it something you are aware of?
@camelid
I have found the exact line that creates the problem
The original function was:
use bson::{doc};
use bson::oid::ObjectId;
use mongodb::{error::Error, Collection, options::FindOneOptions};
#[derive(Clone)]
pub struct UserService {
collection: Collection,
}
impl UserService {
pub async fn get_all(&self) -> Result<Vec<UserSchema>, Error> {
let mut cursor = self.collection.find(None, None).await?; // That's the bad line
let mut vec: Vec<UserSchema> = Vec::new();
while let Some(result) = cursor.next().await {
match result {
Ok(document) => {
let user: UserSchema = bson::from_bson(bson::Bson::Document(document)).unwrap();
vec.push(user);
}
Err(e) => return Err(e.into()),
}
};
Ok(vec)
}
}
By removing chunks of code one by one, I isolated the offending line of code as being:
let mut cursor = self.collection.find(None, None).await?; // That's the bad line
Which is a call to the MongoDB driver
Lifting the code out of the function inside a .then fixes the issue:
self.collection.find(None, None)
.then(|mut res| async {
let mut cursor = res.unwrap();
let mut users: Vec<UserSchema> = Vec::new();
while let Some(result) = cursor.next().await {
match result {
Ok(document) => {
let trader: UserSchema = bson::from_bson(bson::Bson::Document(document)).unwrap();
users.push(trader);
}
Err(e) => return Err(e),
}
};
Ok(current_traders)
});
It is of course not so great to do that, but I hope it will help you in finding the bug
How long is your normal compile time in 1.44 ?
If possible, since we don't have access to your code,
would you mind running bisect to find a blamed commit ?
The general guide is here: https://github.com/rust-lang/cargo-bisect-rustc/blob/master/TUTORIAL.md.
The start date could be the date starting development of 1.46,
which maybe 2020-06-05.
probably related to https://github.com/rust-lang/rust/issues/75992, currently waiting for an MVCE for that issue
@lzutao It takes around 1:45 minutes (in debug with dependencies cached)
I will run the bisection now
@lzutao It takes around 1:45 minutes (in debug with dependencies cached)
Took much longer than I thought, so bisection is possible, but you might not want
to do it in your local host.
@lzutao I need to go anyway, so I'll let it run for a few hours, I'll report if I find something
The command:
cargo bisect-rustc --start=2020-07-01 --end=2020-10-07
probably related to #75992, currently waiting for an MVCE for that issue
@lzutao
Regression in 0a49057dd35d9bd2fcc9760a054809c30eee2a58
searched nightlies: from nightly-2020-08-13 to nightly-2020-08-14
regressed nightly: nightly-2020-08-14
searched commits: from https://github.com/rust-lang/rust/commit/576d27c5a6c80cd39ef57d7398831d8e177573cc to https://github.com/rust-lang/rust/commit/81dc88f88f92ba8ad7465f9cba10c12d3a7b70f1
regressed commit: https://github.com/rust-lang/rust/commit/0a49057dd35d9bd2fcc9760a054809c30eee2a58
bisected with cargo-bisect-rustc v0.5.2
Host triple: x86_64-unknown-linux-gnu
Reproduce with:
cargo bisect-rustc --start=2020-08-13 --end=2020-08-14
This is the same regressed commit as #75992, so closing as a duplicate of #75992.
Thank you very much @sakex for taking the time to bisect this!
Duplicate of #75992.
Hmm, I thought that would mark it in GitHub...
Most helpful comment
75992 also regressed in 1.46.0, so this is likely to be a duplicate