2023-12-23 19:27:36 +01:00
|
|
|
use crate::builder::types::Action;
|
2023-12-26 21:44:19 +01:00
|
|
|
use crate::db::prelude::{Builds, Packages};
|
|
|
|
use crate::db::{builds, packages};
|
2023-12-23 19:27:36 +01:00
|
|
|
use crate::repo::repo::add_pkg;
|
2023-12-26 21:44:19 +01:00
|
|
|
use anyhow::anyhow;
|
|
|
|
use sea_orm::{ActiveModelTrait, DatabaseConnection, EntityTrait, Set};
|
|
|
|
use std::ops::Add;
|
2024-01-01 23:07:52 +01:00
|
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
2023-12-26 21:44:19 +01:00
|
|
|
use tokio::sync::broadcast;
|
|
|
|
use tokio::sync::broadcast::error::RecvError;
|
2023-12-23 19:27:36 +01:00
|
|
|
use tokio::sync::broadcast::Sender;
|
|
|
|
|
|
|
|
pub async fn init(db: DatabaseConnection, tx: Sender<Action>) {
|
|
|
|
loop {
|
|
|
|
if let Ok(_result) = tx.subscribe().recv().await {
|
|
|
|
match _result {
|
|
|
|
// add a package to parallel build
|
2023-12-23 23:00:30 +01:00
|
|
|
Action::Build(name, version, url, mut version_model) => {
|
2023-12-23 19:27:36 +01:00
|
|
|
let db = db.clone();
|
2023-12-26 21:44:19 +01:00
|
|
|
let build = builds::ActiveModel {
|
|
|
|
pkg_id: version_model.package_id.clone(),
|
|
|
|
version_id: version_model.id.clone(),
|
|
|
|
ouput: Set(None),
|
|
|
|
status: Set(Some(0)),
|
2024-01-01 23:07:52 +01:00
|
|
|
start_time: Set(Some(
|
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
.unwrap()
|
|
|
|
.as_secs() as u32,
|
|
|
|
)),
|
2023-12-26 21:44:19 +01:00
|
|
|
..Default::default()
|
|
|
|
};
|
2023-12-26 23:14:00 +01:00
|
|
|
let mut new_build = build.save(&db).await.unwrap();
|
2023-12-26 21:44:19 +01:00
|
|
|
|
2023-12-23 23:00:30 +01:00
|
|
|
// spawn new thread for each pkg build
|
2023-12-26 21:44:19 +01:00
|
|
|
// todo add queue and build two packages in parallel
|
2023-12-23 19:27:36 +01:00
|
|
|
tokio::spawn(async move {
|
2023-12-26 21:44:19 +01:00
|
|
|
let (tx, mut rx) = broadcast::channel::<String>(3);
|
|
|
|
|
|
|
|
let db2 = db.clone();
|
2023-12-26 23:14:00 +01:00
|
|
|
let new_build2 = new_build.clone();
|
2023-12-26 21:44:19 +01:00
|
|
|
tokio::spawn(async move {
|
|
|
|
loop {
|
|
|
|
match rx.recv().await {
|
|
|
|
Ok(output_line) => {
|
|
|
|
println!("{output_line}");
|
|
|
|
|
|
|
|
let _ = append_db_log_output(
|
|
|
|
&db2,
|
|
|
|
output_line,
|
2023-12-26 23:14:00 +01:00
|
|
|
new_build2.id.clone().unwrap(),
|
2023-12-26 21:44:19 +01:00
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
Err(e) => match e {
|
|
|
|
RecvError::Closed => {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
RecvError::Lagged(_) => {}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
match add_pkg(url, version, name, tx).await {
|
2023-12-23 23:00:30 +01:00
|
|
|
Ok(pkg_file_name) => {
|
2023-12-23 19:27:36 +01:00
|
|
|
println!("successfully built package");
|
2023-12-26 21:44:19 +01:00
|
|
|
let _ = set_pkg_status(
|
|
|
|
&db,
|
|
|
|
version_model.package_id.clone().unwrap(),
|
2024-01-01 23:07:52 +01:00
|
|
|
version_model.id.clone().unwrap(),
|
|
|
|
Some(false),
|
2023-12-26 21:44:19 +01:00
|
|
|
1,
|
|
|
|
)
|
|
|
|
.await;
|
2023-12-23 19:27:36 +01:00
|
|
|
|
2023-12-23 23:00:30 +01:00
|
|
|
version_model.file_name = Set(Some(pkg_file_name));
|
2023-12-26 21:44:19 +01:00
|
|
|
let _ = version_model.update(&db).await;
|
2023-12-26 23:14:00 +01:00
|
|
|
|
|
|
|
new_build.status = Set(Some(1));
|
2024-01-01 23:07:52 +01:00
|
|
|
new_build.end_time = Set(Some(
|
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
.unwrap()
|
|
|
|
.as_secs() as u32,
|
|
|
|
));
|
2023-12-26 23:14:00 +01:00
|
|
|
let _ = new_build.update(&db).await;
|
2023-12-23 19:27:36 +01:00
|
|
|
}
|
|
|
|
Err(e) => {
|
2023-12-26 21:44:19 +01:00
|
|
|
let _ = set_pkg_status(
|
|
|
|
&db,
|
|
|
|
version_model.package_id.clone().unwrap(),
|
2024-01-01 23:07:52 +01:00
|
|
|
version_model.id.clone().unwrap(),
|
|
|
|
None,
|
2023-12-26 21:44:19 +01:00
|
|
|
2,
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
let _ = version_model.update(&db).await;
|
2023-12-23 23:00:30 +01:00
|
|
|
|
2023-12-29 18:13:51 +01:00
|
|
|
new_build.status = Set(Some(2));
|
2024-01-01 23:07:52 +01:00
|
|
|
new_build.end_time = Set(Some(
|
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(UNIX_EPOCH)
|
|
|
|
.unwrap()
|
|
|
|
.as_secs() as u32,
|
|
|
|
));
|
2023-12-26 23:14:00 +01:00
|
|
|
let _ = new_build.update(&db).await;
|
|
|
|
|
2023-12-23 19:27:36 +01:00
|
|
|
println!("Error: {e}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-26 21:44:19 +01:00
|
|
|
|
|
|
|
// todo maybe move to helper file
|
|
|
|
async fn set_pkg_status(
|
|
|
|
db: &DatabaseConnection,
|
|
|
|
package_id: i32,
|
2024-01-01 23:07:52 +01:00
|
|
|
version_id: i32,
|
|
|
|
outofdate: Option<bool>,
|
2023-12-26 21:44:19 +01:00
|
|
|
status: i32,
|
|
|
|
) -> anyhow::Result<()> {
|
2023-12-26 23:14:00 +01:00
|
|
|
let mut pkg: packages::ActiveModel = Packages::find_by_id(package_id)
|
2023-12-26 21:44:19 +01:00
|
|
|
.one(db)
|
|
|
|
.await?
|
2023-12-26 23:14:00 +01:00
|
|
|
.ok_or(anyhow!("no package with id {package_id} found"))?
|
|
|
|
.into();
|
2023-12-26 21:44:19 +01:00
|
|
|
|
2023-12-26 23:14:00 +01:00
|
|
|
pkg.status = Set(status);
|
2024-01-01 23:07:52 +01:00
|
|
|
pkg.latest_version_id = Set(Some(version_id));
|
|
|
|
if outofdate.is_some() {
|
|
|
|
pkg.out_of_date = Set(outofdate.unwrap() as i32)
|
|
|
|
}
|
2023-12-26 21:44:19 +01:00
|
|
|
pkg.update(db).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn append_db_log_output(
|
|
|
|
db: &DatabaseConnection,
|
|
|
|
text: String,
|
|
|
|
build_id: i32,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
let build = Builds::find_by_id(build_id)
|
|
|
|
.one(db)
|
|
|
|
.await?
|
|
|
|
.ok_or(anyhow!("build not found"))?;
|
|
|
|
|
|
|
|
let mut build: builds::ActiveModel = build.into();
|
|
|
|
|
|
|
|
match build.ouput.unwrap() {
|
|
|
|
None => {
|
|
|
|
build.ouput = Set(Some(text.add("\n")));
|
|
|
|
}
|
|
|
|
Some(s) => {
|
|
|
|
build.ouput = Set(Some(s.add(text.as_str()).add("\n")));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
build.update(db).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|