Skip to content

Commit 046037e

Browse files
committed
extend and improve data-collection for release-activity graph
1 parent cdc7a53 commit 046037e

File tree

3 files changed

+47
-73
lines changed

3 files changed

+47
-73
lines changed

src/db/migrate.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,28 @@ pub fn migrate(version: Option<Version>, conn: &mut Client) -> CratesfyiResult<(
618618
DROP INDEX github_repos_stars_idx;
619619
",
620620
),
621+
migration!(
622+
context,
623+
27,
624+
"create materialized view for release-statistics",
625+
"
626+
CREATE MATERIALIZED VIEW releases_statistics AS
627+
SELECT
628+
release_time::date as date,
629+
count(*) AS counts,
630+
count(CASE WHEN is_library = TRUE AND build_status = FALSE THEN 1 ELSE 0 END) AS failures
631+
FROM
632+
releases
633+
GROUP BY
634+
release_time::date
635+
;
636+
CREATE INDEX releases_statistics_date_idx ON releases_statistics (date);
637+
",
638+
"
639+
DROP INDEX releases_statistics_date_idx;
640+
DROP MATERIALIZED VIEW releases_statistics;
641+
",
642+
),
621643
];
622644

623645
for migration in migrations {

src/utils/release_activity_updater.rs

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,8 @@
11
use crate::error::Result;
2-
use chrono::{Duration, Utc};
32
use postgres::Client;
4-
use serde_json::{Map, Value};
53

64
pub fn update_release_activity(conn: &mut Client) -> Result<()> {
7-
let mut dates = Vec::with_capacity(30);
8-
let mut crate_counts = Vec::with_capacity(30);
9-
let mut failure_counts = Vec::with_capacity(30);
10-
11-
for day in 0..30 {
12-
let rows = conn.query(
13-
format!(
14-
"SELECT COUNT(*)
15-
FROM releases
16-
WHERE release_time < NOW() - INTERVAL '{} day' AND
17-
release_time > NOW() - INTERVAL '{} day'",
18-
day,
19-
day + 1
20-
)
21-
.as_str(),
22-
&[],
23-
)?;
24-
let failures_count_rows = conn.query(
25-
format!(
26-
"SELECT COUNT(*)
27-
FROM releases
28-
WHERE is_library = TRUE AND
29-
build_status = FALSE AND
30-
release_time < NOW() - INTERVAL '{} day' AND
31-
release_time > NOW() - INTERVAL '{} day'",
32-
day,
33-
day + 1
34-
)
35-
.as_str(),
36-
&[],
37-
)?;
38-
39-
let release_count: i64 = rows[0].get(0);
40-
let failure_count: i64 = failures_count_rows[0].get(0);
41-
let now = Utc::now().naive_utc();
42-
let date = now - Duration::days(day);
43-
44-
dates.push(format!("{}", date.format("%d %b")));
45-
crate_counts.push(release_count);
46-
failure_counts.push(failure_count);
47-
}
48-
49-
dates.reverse();
50-
crate_counts.reverse();
51-
failure_counts.reverse();
52-
53-
let map = {
54-
let mut map = Map::new();
55-
map.insert("dates".to_owned(), serde_json::to_value(dates)?);
56-
map.insert("counts".to_owned(), serde_json::to_value(crate_counts)?);
57-
map.insert("failures".to_owned(), serde_json::to_value(failure_counts)?);
58-
59-
Value::Object(map)
60-
};
61-
62-
conn.query(
63-
"INSERT INTO config (name, value) VALUES ('release_activity', $1)
64-
ON CONFLICT (name) DO UPDATE
65-
SET value = $1 WHERE config.name = 'release_activity'",
66-
&[&map],
67-
)?;
5+
conn.execute("REFRESH MATERIALIZED VIEW releases_statistics", &[])?;
686

697
Ok(())
708
}

src/web/releases.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
web::{error::Nope, match_version, page::WebPage, redirect_base},
88
BuildQueue, Config,
99
};
10-
use chrono::{DateTime, Utc};
10+
use chrono::{DateTime, NaiveDate, Utc};
1111
use iron::{
1212
headers::{ContentType, Expires, HttpDate},
1313
mime::{Mime, SubLevel, TopLevel},
@@ -17,7 +17,7 @@ use iron::{
1717
use postgres::Client;
1818
use router::Router;
1919
use serde::Serialize;
20-
use serde_json::Value;
20+
use serde_json::{json, Value};
2121

2222
/// Number of release in home page
2323
const RELEASES_IN_HOME: i64 = 15;
@@ -668,20 +668,34 @@ impl_webpage! {
668668

669669
pub fn activity_handler(req: &mut Request) -> IronResult<Response> {
670670
let mut conn = extension!(req, Pool).get()?;
671-
let activity_data: Value = ctry!(
671+
672+
let data: Vec<(NaiveDate, i64, i64)> = ctry!(
672673
req,
673674
conn.query(
674-
"SELECT value FROM config WHERE name = 'release_activity'",
675-
&[]
676-
),
675+
"SELECT
676+
date,
677+
counts,
678+
failures
679+
FROM releases_statistics
680+
WHERE date >= CURRENT_DATE - INTERVAL '30 days'
681+
ORDER BY date DESC
682+
",
683+
&[],
684+
)
677685
)
678-
.iter()
679-
.next()
680-
.map_or(Value::Null, |row| row.get("value"));
686+
.into_iter()
687+
.map(|row| (row.get(0), row.get(1), row.get(2)))
688+
.collect();
681689

682690
ReleaseActivity {
683691
description: "Monthly release activity",
684-
activity_data,
692+
activity_data: json!(
693+
{
694+
"dates": data.iter().map(|&d| d.0.format("%d %b").to_string()).collect::<Vec<_>>(),
695+
"counts": data.iter().map(|&d| d.1).collect::<Vec<_>>(),
696+
"failures": data.iter().map(|&d| d.2).collect::<Vec<_>>(),
697+
}
698+
),
685699
}
686700
.into_response(req)
687701
}

0 commit comments

Comments
 (0)