Skip to content

Commit 1c7fb6a

Browse files
committed
Move the typosquat cache into Environment.
1 parent 3f1d514 commit 1c7fb6a

File tree

8 files changed

+46
-46
lines changed

8 files changed

+46
-46
lines changed

src/background_jobs.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::swirl::errors::EnqueueError;
1414
use crate::swirl::PerformError;
1515
use crate::worker::cloudfront::CloudFront;
1616
use crate::worker::fastly::Fastly;
17+
use crate::worker::typosquat::Cache as TyposquatCache;
1718
use crate::{worker, Emails};
1819
use crates_io_index::Repository;
1920

@@ -348,6 +349,7 @@ pub struct Environment {
348349
emails: Emails,
349350
fastly: Option<Fastly>,
350351
pub storage: AssertUnwindSafe<Arc<Storage>>,
352+
typosquat_cache: TyposquatCache,
351353
}
352354

353355
impl Environment {
@@ -358,6 +360,7 @@ impl Environment {
358360
emails: Emails,
359361
fastly: Option<Fastly>,
360362
storage: Arc<Storage>,
363+
typosquat_cache: TyposquatCache,
361364
) -> Self {
362365
Self::new_shared(
363366
Arc::new(Mutex::new(index)),
@@ -366,6 +369,7 @@ impl Environment {
366369
emails,
367370
fastly,
368371
storage,
372+
typosquat_cache,
369373
)
370374
}
371375

@@ -376,6 +380,7 @@ impl Environment {
376380
emails: Emails,
377381
fastly: Option<Fastly>,
378382
storage: Arc<Storage>,
383+
typosquat_cache: TyposquatCache,
379384
) -> Self {
380385
Self {
381386
index,
@@ -384,6 +389,7 @@ impl Environment {
384389
emails,
385390
fastly,
386391
storage: AssertUnwindSafe(storage),
392+
typosquat_cache,
387393
}
388394
}
389395

@@ -410,4 +416,8 @@ impl Environment {
410416
pub(crate) fn fastly(&self) -> Option<&Fastly> {
411417
self.fastly.as_ref()
412418
}
419+
420+
pub(crate) fn typosquat_cache(&self) -> &TyposquatCache {
421+
&self.typosquat_cache
422+
}
413423
}

src/bin/background-worker.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::thread::sleep;
2727
use std::time::{Duration, Instant};
2828

2929
use crates_io::swirl;
30-
use crates_io::worker::fastly::Fastly;
30+
use crates_io::worker::{fastly::Fastly, typosquat::Cache as TyposquatCache};
3131

3232
fn main() {
3333
let _sentry = crates_io::sentry::init();
@@ -77,14 +77,22 @@ fn main() {
7777
let emails = Emails::from_environment(&config);
7878
let fastly = Fastly::from_environment();
7979
let storage = Arc::new(Storage::from_config(&config.storage));
80+
let typosquat_cache = TyposquatCache::default();
8081

8182
let client = Client::builder()
8283
.timeout(Duration::from_secs(45))
8384
.build()
8485
.expect("Couldn't build client");
8586

86-
let environment =
87-
Environment::new_shared(repository, client, cloudfront, emails, fastly, storage);
87+
let environment = Environment::new_shared(
88+
repository,
89+
client,
90+
cloudfront,
91+
emails,
92+
fastly,
93+
storage,
94+
typosquat_cache,
95+
);
8896

8997
let environment = Arc::new(Some(environment));
9098

src/tests/util/test_app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::{MockAnonymousUser, MockCookieUser, MockTokenUser};
22
use crate::util::{chaosproxy::ChaosProxy, fresh_schema::FreshSchema};
33
use crates_io::config::{self, BalanceCapacityConfig, Base, DatabasePools, DbPoolConfig};
44
use crates_io::storage::StorageConfig;
5+
use crates_io::worker::typosquat::Cache as TyposquatCache;
56
use crates_io::{background_jobs::Environment, env, App, Emails, Env};
67
use crates_io_index::testing::UpstreamIndex;
78
use crates_io_index::{Credentials, Repository as WorkerRepository, RepositoryConfig};
@@ -260,6 +261,7 @@ impl TestAppBuilder {
260261
Emails::new_in_memory(),
261262
None,
262263
app.storage.clone(),
264+
TyposquatCache::default(),
263265
);
264266

265267
Some(Runner::test_runner(

src/worker/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub mod dump_db;
99
pub mod fastly;
1010
mod git;
1111
mod readmes;
12-
mod typosquat;
12+
pub mod typosquat;
1313
mod update_downloads;
1414

1515
pub(crate) use daily_db_maintenance::perform_daily_db_maintenance;

src/worker/typosquat.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ mod cache;
99
mod config;
1010
mod types;
1111

12+
pub use cache::Cache;
13+
1214
#[cfg(test)]
1315
mod test_util;
1416

@@ -18,18 +20,19 @@ pub fn check_typosquat(
1820
conn: &mut PgConnection,
1921
name: &str,
2022
) -> Result<(), PerformError> {
21-
check_typosquat_inner(env.emails(), conn, name)
23+
check_typosquat_inner(env.emails(), env.typosquat_cache(), conn, name)
2224
}
2325

2426
fn check_typosquat_inner(
2527
emails: &Emails,
28+
cache: &Cache,
2629
conn: &mut PgConnection,
2730
name: &str,
2831
) -> Result<(), PerformError> {
2932
info!("Checking new crate for potential typosquatting");
3033

3134
let krate: Box<dyn Package> = Box::new(OwnedCrate::from_name(conn, name)?);
32-
let squats = cache::get_harness(conn)?.check_package(name, krate)?;
35+
let squats = cache.get(conn)?.check_package(name, krate)?;
3336
if !squats.is_empty() {
3437
// Well, well, well. For now, the only action we'll take is to e-mail people who hopefully
3538
// care to check into things more closely.
@@ -66,7 +69,8 @@ mod tests {
6669
// Note that there's theoretical flakiness here if the test takes longer to run than the
6770
// cache TTL. Of course, since the cache TTL is currently set to 12 hours, that would
6871
// probably indicate bigger problems.
69-
let _harness = super::cache::get_harness(faker.borrow_conn())?;
72+
let cache = Cache::default();
73+
let _harness = cache.get(faker.borrow_conn())?;
7074

7175
// Now we'll create new crates: one problematic, one not so.
7276
let other_user = faker.user("b")?;
@@ -87,11 +91,11 @@ mod tests {
8791
let mut conn = faker.into_conn();
8892

8993
// Run the check with a crate that shouldn't cause problems.
90-
check_typosquat_inner(&emails, &mut conn, &angel.name)?;
94+
check_typosquat_inner(&emails, &cache, &mut conn, &angel.name)?;
9195
assert!(emails.mails_in_memory().unwrap().is_empty());
9296

9397
// Now run the check with a less innocent crate.
94-
check_typosquat_inner(&emails, &mut conn, &demon.name)?;
98+
check_typosquat_inner(&emails, &cache, &mut conn, &demon.name)?;
9599
assert!(!emails.mails_in_memory().unwrap().is_empty());
96100

97101
Ok(())

src/worker/typosquat/cache.rs

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,10 @@ use crate::swirl::PerformError;
1313

1414
use super::{config, types::TopCrates};
1515

16-
/// Gets the typomania harness for the cached top crates, regenerating it if it is out of date.
17-
pub(super) fn get_harness(
18-
conn: &mut PgConnection,
19-
) -> Result<Arc<Harness<TopCrates>>, PerformError> {
20-
HARNESS_CACHE.get(conn)
21-
}
22-
23-
static HARNESS_CACHE: Cache = Cache::new();
24-
25-
struct Cache(Mutex<Inner>);
16+
pub struct Cache(Mutex<Inner>);
2617

2718
impl Cache {
28-
const fn new() -> Self {
29-
Self(Mutex::new(Inner::new()))
30-
}
31-
32-
fn get(&self, conn: &mut PgConnection) -> Result<Arc<Harness<TopCrates>>, PerformError> {
19+
pub fn get(&self, conn: &mut PgConnection) -> Result<Arc<Harness<TopCrates>>, PerformError> {
3320
let mut inner = self.0.lock().unwrap();
3421

3522
Ok(if let Some(harness) = inner.get() {
@@ -43,6 +30,12 @@ impl Cache {
4330
}
4431
}
4532

33+
impl Default for Cache {
34+
fn default() -> Self {
35+
Self(Mutex::new(Inner::new()))
36+
}
37+
}
38+
4639
#[instrument(skip_all)]
4740
fn new_harness(conn: &mut PgConnection) -> Result<Harness<TopCrates>, PerformError> {
4841
debug!("Rebuilding top crate cache");
@@ -71,30 +64,18 @@ fn new_harness(conn: &mut PgConnection) -> Result<Harness<TopCrates>, PerformErr
7164

7265
struct Inner {
7366
harness: Option<Arc<Harness<TopCrates>>>,
74-
last_update: Option<Instant>,
7567
}
7668

7769
impl Inner {
7870
const fn new() -> Self {
79-
Self {
80-
harness: None,
81-
last_update: None,
82-
}
71+
Self { harness: None }
8372
}
8473

8574
fn get(&self) -> Option<Arc<Harness<TopCrates>>> {
86-
if let Some(harness) = &self.harness {
87-
if let Some(when) = self.last_update {
88-
if when >= Instant::now() - config::CACHE_TTL {
89-
return Some(harness.clone());
90-
}
91-
}
92-
}
93-
None
75+
self.harness.clone()
9476
}
9577

9678
fn update(&mut self, harness: Arc<Harness<TopCrates>>) {
9779
self.harness = Some(harness);
98-
self.last_update = Some(Instant::now());
9980
}
10081
}

src/worker/typosquat/config.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
//! Things that should really be read from a configuration file, but are just hardcoded while we
22
//! experiment with this.
33
4-
use std::time::Duration;
5-
6-
/// How long to cache the top crates for.
7-
pub(super) static CACHE_TTL: Duration = Duration::from_secs(12 * 60 * 60);
8-
94
/// Valid characters in crate names.
105
pub(super) static CRATE_NAME_ALPHABET: &str =
116
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_";

src/worker/typosquat/types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ use crate::{
1717
/// A corpus of the current top crates on crates.io, as determined by their download counts, along
1818
/// with their ownership information so we can quickly check if a new crate shares owners with a
1919
/// top crate.
20-
pub(super) struct TopCrates {
20+
pub struct TopCrates {
2121
crates: HashMap<String, OwnedCrate>,
2222
}
2323

2424
impl TopCrates {
2525
/// Retrieves the `num` top crates from the database.
26-
pub(super) fn new(conn: &mut PgConnection, num: i64) -> Result<Self, PerformError> {
26+
pub fn new(conn: &mut PgConnection, num: i64) -> Result<Self, PerformError> {
2727
// We have to build up a data structure that contains the top crates, their owners in some
2828
// form that is easily compared, and that can be indexed by the crate name.
2929
//
@@ -87,7 +87,7 @@ impl TopCrates {
8787
}
8888

8989
/// Iterates over the names of the top crates.
90-
pub(super) fn iter_names(&self) -> impl Iterator<Item = &str> {
90+
pub fn iter_names(&self) -> impl Iterator<Item = &str> {
9191
self.crates.keys().map(String::as_str)
9292
}
9393
}

0 commit comments

Comments
 (0)