mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2025-01-03 15:06:01 +03:00
protect vbranches with a semaphore
This commit is contained in:
parent
77c00a0723
commit
9b5e6eec2b
@ -1,7 +1,7 @@
|
|||||||
use std::{collections::HashMap, ops, sync};
|
use std::{collections::HashMap, ops, sync};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::{mpsc, Semaphore};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -29,6 +29,8 @@ pub struct App {
|
|||||||
files_database: files::Database,
|
files_database: files::Database,
|
||||||
deltas_database: deltas::Database,
|
deltas_database: deltas::Database,
|
||||||
bookmarks_database: bookmarks::Database,
|
bookmarks_database: bookmarks::Database,
|
||||||
|
|
||||||
|
vbranch_semaphores: sync::Arc<tokio::sync::Mutex<HashMap<String, Semaphore>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
@ -63,6 +65,7 @@ impl App {
|
|||||||
deltas_database: deltas::Database::new(database.clone()),
|
deltas_database: deltas::Database::new(database.clone()),
|
||||||
files_database: files::Database::new(database.clone()),
|
files_database: files::Database::new(database.clone()),
|
||||||
bookmarks_database: bookmarks::Database::new(database),
|
bookmarks_database: bookmarks::Database::new(database),
|
||||||
|
vbranch_semaphores: sync::Arc::new(tokio::sync::Mutex::new(HashMap::new())),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +336,7 @@ impl App {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_virtual_branches(
|
pub async fn list_virtual_branches(
|
||||||
&self,
|
&self,
|
||||||
project_id: &str,
|
project_id: &str,
|
||||||
) -> Result<Vec<virtual_branches::VirtualBranch>> {
|
) -> Result<Vec<virtual_branches::VirtualBranch>> {
|
||||||
@ -341,11 +344,30 @@ impl App {
|
|||||||
let project = self.gb_project(project_id)?;
|
let project = self.gb_project(project_id)?;
|
||||||
let project_repository = project_repository::Repository::open(&project)
|
let project_repository = project_repository::Repository::open(&project)
|
||||||
.context("failed to open project repository")?;
|
.context("failed to open project repository")?;
|
||||||
|
|
||||||
|
let mut semaphores = self.vbranch_semaphores.lock().await;
|
||||||
|
let semaphore = semaphores
|
||||||
|
.entry(project_id.to_string())
|
||||||
|
.or_insert_with(|| Semaphore::new(1));
|
||||||
|
let _permit = semaphore.acquire().await?;
|
||||||
|
|
||||||
virtual_branches::list_virtual_branches(&gb_repository, &project_repository)
|
virtual_branches::list_virtual_branches(&gb_repository, &project_repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_virtual_branch(&self, project_id: &str, name: &str, path: &str) -> Result<()> {
|
pub async fn create_virtual_branch(
|
||||||
|
&self,
|
||||||
|
project_id: &str,
|
||||||
|
name: &str,
|
||||||
|
path: &str,
|
||||||
|
) -> Result<()> {
|
||||||
let gb_repository = self.gb_repository(project_id)?;
|
let gb_repository = self.gb_repository(project_id)?;
|
||||||
|
|
||||||
|
let mut semaphores = self.vbranch_semaphores.lock().await;
|
||||||
|
let semaphore = semaphores
|
||||||
|
.entry(project_id.to_string())
|
||||||
|
.or_insert_with(|| Semaphore::new(1));
|
||||||
|
let _permit = semaphore.acquire().await?;
|
||||||
|
|
||||||
let branch_id = virtual_branches::create_virtual_branch(&gb_repository, name)?;
|
let branch_id = virtual_branches::create_virtual_branch(&gb_repository, name)?;
|
||||||
virtual_branches::move_files(&gb_repository, &branch_id, &vec![path.try_into()?])?;
|
virtual_branches::move_files(&gb_repository, &branch_id, &vec![path.try_into()?])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -361,7 +383,7 @@ impl App {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_virtual_branch_files(
|
pub async fn move_virtual_branch_files(
|
||||||
&self,
|
&self,
|
||||||
project_id: &str,
|
project_id: &str,
|
||||||
branch: &str,
|
branch: &str,
|
||||||
@ -372,6 +394,13 @@ impl App {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|p| p.try_into())
|
.map(|p| p.try_into())
|
||||||
.collect::<Result<Vec<branch::Ownership>, _>>()?;
|
.collect::<Result<Vec<branch::Ownership>, _>>()?;
|
||||||
|
|
||||||
|
let mut semaphores = self.vbranch_semaphores.lock().await;
|
||||||
|
let semaphore = semaphores
|
||||||
|
.entry(project_id.to_string())
|
||||||
|
.or_insert_with(|| Semaphore::new(1));
|
||||||
|
let _permit = semaphore.acquire().await?;
|
||||||
|
|
||||||
virtual_branches::move_files(&gb_repository, branch, &paths)?;
|
virtual_branches::move_files(&gb_repository, branch, &paths)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -577,6 +577,7 @@ async fn list_virtual_branches(
|
|||||||
let app = handle.state::<app::App>();
|
let app = handle.state::<app::App>();
|
||||||
let branches = app
|
let branches = app
|
||||||
.list_virtual_branches(project_id)
|
.list_virtual_branches(project_id)
|
||||||
|
.await
|
||||||
.context("failed to list virtual branches")?;
|
.context("failed to list virtual branches")?;
|
||||||
Ok(branches)
|
Ok(branches)
|
||||||
}
|
}
|
||||||
@ -590,7 +591,9 @@ async fn create_virtual_branch(
|
|||||||
path: &str,
|
path: &str,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let app = handle.state::<app::App>();
|
let app = handle.state::<app::App>();
|
||||||
app.create_virtual_branch(project_id, name, path)?;
|
app.create_virtual_branch(project_id, name, path)
|
||||||
|
.await
|
||||||
|
.context("failed to create virtual branch")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +618,10 @@ async fn move_virtual_branch_files(
|
|||||||
paths: Vec<&str>,
|
paths: Vec<&str>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let app = handle.state::<app::App>();
|
let app = handle.state::<app::App>();
|
||||||
let target = app.move_virtual_branch_files(project_id, branch, paths)?;
|
let target = app
|
||||||
|
.move_virtual_branch_files(project_id, branch, paths)
|
||||||
|
.await
|
||||||
|
.context("failed to move virtual branch files")?;
|
||||||
Ok(target)
|
Ok(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ use serde::Serialize;
|
|||||||
|
|
||||||
pub use branch::Branch;
|
pub use branch::Branch;
|
||||||
pub use iterator::BranchIterator as Iterator;
|
pub use iterator::BranchIterator as Iterator;
|
||||||
|
use tokio::sync::Semaphore;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{gb_repository, project_repository, reader, sessions};
|
use crate::{gb_repository, project_repository, reader, sessions};
|
||||||
|
Loading…
Reference in New Issue
Block a user