Skip to content

Commit 0e91690

Browse files
committed
Unify DocBuilder and BuildQueue
There was no reason to have these be separate. This also gets rid of some extra open database connections.
1 parent 2fb6bdc commit 0e91690

File tree

8 files changed

+145
-169
lines changed

8 files changed

+145
-169
lines changed

src/bin/cratesfyi.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use docs_rs::db::{self, add_path_into_database, Pool, PoolClient};
88
use docs_rs::repositories::RepositoryStatsUpdater;
99
use docs_rs::utils::{remove_crate_priority, set_crate_priority};
1010
use docs_rs::{
11-
BuildQueue, Config, Context, DocBuilder, Index, Metrics, PackageKind, RustwideBuilder, Server,
12-
Storage,
11+
BuildQueue, Config, Context, Index, Metrics, PackageKind, RustwideBuilder, Server, Storage,
1312
};
1413
use once_cell::sync::OnceCell;
1514
use structopt::StructOpt;
@@ -289,7 +288,7 @@ enum BuildSubcommand {
289288

290289
impl BuildSubcommand {
291290
pub fn handle_args(self, ctx: BinContext, skip_if_exists: bool) -> Result<()> {
292-
let docbuilder = DocBuilder::new(ctx.build_queue()?);
291+
let build_queue = ctx.build_queue()?;
293292

294293
let rustwide_builder = || -> Result<RustwideBuilder> {
295294
let mut builder = RustwideBuilder::init(&ctx)?;
@@ -358,8 +357,8 @@ impl BuildSubcommand {
358357
.context("failed to add essential files")?;
359358
}
360359

361-
Self::Lock => docbuilder.lock().context("Failed to lock")?,
362-
Self::Unlock => docbuilder.unlock().context("Failed to unlock")?,
360+
Self::Lock => build_queue.lock().context("Failed to lock")?,
361+
Self::Unlock => build_queue.unlock().context("Failed to unlock")?,
363362
}
364363

365364
Ok(())

src/build_queue.rs

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
use crate::db::Pool;
2+
use crate::docbuilder::PackageKind;
23
use crate::error::Result;
3-
use crate::{Config, Metrics};
4-
use log::error;
4+
use crate::utils::get_crate_priority;
5+
use crate::{Config, Index, Metrics, RustwideBuilder};
6+
7+
use crates_index_diff::ChangeKind;
8+
use log::{debug, error};
9+
10+
use std::fs;
511
use std::path::PathBuf;
612
use std::sync::Arc;
713

@@ -33,15 +39,6 @@ impl BuildQueue {
3339
}
3440
}
3541

36-
pub(crate) fn lock_path(&self) -> PathBuf {
37-
self.config.prefix.join("docsrs.lock")
38-
}
39-
40-
/// Checks for the lock file and returns whether it currently exists.
41-
pub fn is_locked(&self) -> bool {
42-
self.lock_path().exists()
43-
}
44-
4542
pub fn add_crate(
4643
&self,
4744
name: &str,
@@ -145,6 +142,130 @@ impl BuildQueue {
145142
}
146143
}
147144

145+
/// Locking functions.
146+
impl BuildQueue {
147+
pub(crate) fn lock_path(&self) -> PathBuf {
148+
self.config.prefix.join("docsrs.lock")
149+
}
150+
151+
/// Checks for the lock file and returns whether it currently exists.
152+
pub fn is_locked(&self) -> bool {
153+
self.lock_path().exists()
154+
}
155+
156+
/// Creates a lock file. Daemon will check this lock file and stop operating if its exists.
157+
pub fn lock(&self) -> Result<()> {
158+
let path = self.lock_path();
159+
if !path.exists() {
160+
fs::OpenOptions::new().write(true).create(true).open(path)?;
161+
}
162+
163+
Ok(())
164+
}
165+
166+
/// Removes lock file.
167+
pub fn unlock(&self) -> Result<()> {
168+
let path = self.lock_path();
169+
if path.exists() {
170+
fs::remove_file(path)?;
171+
}
172+
173+
Ok(())
174+
}
175+
}
176+
177+
/// Index methods.
178+
impl BuildQueue {
179+
/// Updates registry index repository and adds new crates into build queue.
180+
///
181+
/// Returns the number of crates added
182+
pub fn get_new_crates(&self, index: &Index) -> Result<usize> {
183+
let mut conn = self.db.get()?;
184+
let diff = index.diff()?;
185+
let (mut changes, oid) = diff.peek_changes()?;
186+
let mut crates_added = 0;
187+
188+
// I believe this will fix ordering of queue if we get more than one crate from changes
189+
changes.reverse();
190+
191+
for krate in &changes {
192+
match krate.kind {
193+
ChangeKind::Yanked => {
194+
let res = conn.execute(
195+
"
196+
UPDATE releases
197+
SET yanked = TRUE
198+
FROM crates
199+
WHERE crates.id = releases.crate_id
200+
AND name = $1
201+
AND version = $2
202+
",
203+
&[&krate.name, &krate.version],
204+
);
205+
match res {
206+
Ok(_) => debug!("{}-{} yanked", krate.name, krate.version),
207+
Err(err) => error!(
208+
"error while setting {}-{} to yanked: {}",
209+
krate.name, krate.version, err
210+
),
211+
}
212+
}
213+
214+
ChangeKind::Added => {
215+
let priority = get_crate_priority(&mut conn, &krate.name)?;
216+
217+
match self.add_crate(
218+
&krate.name,
219+
&krate.version,
220+
priority,
221+
index.repository_url(),
222+
) {
223+
Ok(()) => {
224+
debug!("{}-{} added into build queue", krate.name, krate.version);
225+
crates_added += 1;
226+
}
227+
Err(err) => error!(
228+
"failed adding {}-{} into build queue: {}",
229+
krate.name, krate.version, err
230+
),
231+
}
232+
}
233+
}
234+
}
235+
236+
diff.set_last_seen_reference(oid)?;
237+
238+
Ok(crates_added)
239+
}
240+
241+
/// Builds the top package from the queue. Returns whether there was a package in the queue.
242+
///
243+
/// Note that this will return `Ok(true)` even if the package failed to build.
244+
pub(crate) fn build_next_queue_package(&self, builder: &mut RustwideBuilder) -> Result<bool> {
245+
let mut processed = false;
246+
self.process_next_crate(|krate| {
247+
processed = true;
248+
249+
let kind = krate
250+
.registry
251+
.as_ref()
252+
.map(|r| PackageKind::Registry(r.as_str()))
253+
.unwrap_or(PackageKind::CratesIo);
254+
255+
if let Err(err) = builder.update_toolchain() {
256+
log::error!("Updating toolchain failed, locking queue: {}", err);
257+
self.lock()?;
258+
return Err(err);
259+
}
260+
261+
builder.build_package(&krate.name, &krate.version, kind)?;
262+
Ok(())
263+
})?;
264+
265+
Ok(processed)
266+
}
267+
}
268+
148269
#[cfg(test)]
149270
mod tests {
150271
use super::*;

src/docbuilder/mod.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,7 @@
11
mod crates;
22
mod limits;
3-
mod queue;
43
mod rustwide_builder;
54

65
pub(crate) use self::limits::Limits;
76
pub(crate) use self::rustwide_builder::{BuildResult, DocCoverage};
87
pub use self::rustwide_builder::{PackageKind, RustwideBuilder};
9-
10-
use crate::error::Result;
11-
use crate::BuildQueue;
12-
use std::fs;
13-
use std::sync::Arc;
14-
15-
/// chroot based documentation builder
16-
pub struct DocBuilder {
17-
pub(crate) build_queue: Arc<BuildQueue>,
18-
}
19-
20-
impl DocBuilder {
21-
pub fn new(build_queue: Arc<BuildQueue>) -> DocBuilder {
22-
DocBuilder { build_queue }
23-
}
24-
25-
/// Creates a lock file. Daemon will check this lock file and stop operating if its exists.
26-
pub fn lock(&self) -> Result<()> {
27-
let path = self.build_queue.lock_path();
28-
if !path.exists() {
29-
fs::OpenOptions::new().write(true).create(true).open(path)?;
30-
}
31-
32-
Ok(())
33-
}
34-
35-
/// Removes lock file.
36-
pub fn unlock(&self) -> Result<()> {
37-
let path = self.build_queue.lock_path();
38-
if path.exists() {
39-
fs::remove_file(path)?;
40-
}
41-
42-
Ok(())
43-
}
44-
}

src/docbuilder/queue.rs

Lines changed: 0 additions & 102 deletions
This file was deleted.

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
pub use self::build_queue::BuildQueue;
66
pub use self::config::Config;
77
pub use self::context::Context;
8-
pub use self::docbuilder::DocBuilder;
98
pub use self::docbuilder::PackageKind;
109
pub use self::docbuilder::RustwideBuilder;
1110
pub use self::index::Index;

src/test/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl TestEnvironment {
187187
Arc::new(BuildQueue::new(
188188
self.db().pool(),
189189
self.metrics(),
190-
&self.config(),
190+
self.config(),
191191
))
192192
})
193193
.clone()

src/utils/daemon.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! This daemon will start web server, track new packages and build them
44
5-
use crate::{utils::queue_builder, Context, DocBuilder, RustwideBuilder};
5+
use crate::{utils::queue_builder, Context, RustwideBuilder};
66
use anyhow::Error;
77
use log::{debug, error, info};
88
use std::thread;
@@ -21,13 +21,11 @@ fn start_registry_watcher(context: &dyn Context) -> Result<(), Error> {
2121

2222
let mut last_gc = Instant::now();
2323
loop {
24-
let mut doc_builder = DocBuilder::new(build_queue.clone());
25-
26-
if doc_builder.build_queue.is_locked() {
24+
if build_queue.is_locked() {
2725
debug!("Lock file exists, skipping checking new crates");
2826
} else {
2927
debug!("Checking new crates");
30-
match doc_builder.get_new_crates(&index) {
28+
match build_queue.get_new_crates(&index) {
3129
Ok(n) => debug!("{} crates added to queue", n),
3230
Err(e) => error!("Failed to get new crates: {}", e),
3331
}
@@ -62,8 +60,7 @@ pub fn start_daemon(context: &dyn Context, enable_registry_watcher: bool) -> Res
6260
thread::Builder::new()
6361
.name("build queue reader".to_string())
6462
.spawn(move || {
65-
let doc_builder = DocBuilder::new(build_queue.clone());
66-
queue_builder(doc_builder, rustwide_builder, build_queue).unwrap();
63+
queue_builder(rustwide_builder, build_queue).unwrap();
6764
})
6865
.unwrap();
6966

0 commit comments

Comments
 (0)