Merge pull request #3789 from gitbutlerapp/gitbutler-tracked-data-files-implementation

setup for async tasks on oplog update
This commit is contained in:
Kiril Videlov 2024-05-19 16:07:40 +02:00 committed by GitHub
commit bb1b5ce0e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 1 deletions

View File

@ -3,3 +3,5 @@ pub mod oplog;
mod reflog;
pub mod snapshot;
mod state;
pub const OPLOG_FILE_NAME: &str = "operations-log.toml";

View File

@ -7,6 +7,8 @@ use std::{
use serde::{Deserialize, Serialize};
use super::OPLOG_FILE_NAME;
/// This tracks the head of the oplog, persisted in operations-log.toml.
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Oplog {
@ -22,7 +24,7 @@ pub struct OplogHandle {
impl OplogHandle {
/// Creates a new concurrency-safe handle to the state of the oplog.
pub fn new(base_path: &Path) -> Self {
let file_path = base_path.join("operations-log.toml");
let file_path = base_path.join(OPLOG_FILE_NAME);
Self { file_path }
}

View File

@ -13,6 +13,8 @@ pub(super) enum InternalEvent {
// From file monitor
GitFilesChange(ProjectId, Vec<PathBuf>),
ProjectFilesChange(ProjectId, Vec<PathBuf>),
// Triggered on change in the `.git/gitbutler` directory
GitButlerOplogChange(ProjectId),
}
/// This type captures all operations that can be fed into a watcher that runs in the background.
@ -52,6 +54,9 @@ impl Display for InternalEvent {
comma_separated_paths(paths)
)
}
InternalEvent::GitButlerOplogChange(project_id) => {
write!(f, "GitButlerOplogChange({})", project_id)
}
InternalEvent::ProjectFilesChange(project_id, paths) => {
write!(
f,

View File

@ -10,6 +10,7 @@ use notify_debouncer_full::new_debouncer;
use tokio::task;
use tracing::Level;
use gitbutler_core::ops::OPLOG_FILE_NAME;
/// The timeout for debouncing file change events.
/// This is used to prevent multiple events from being sent for a single file change.
const DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100);
@ -114,12 +115,16 @@ pub fn spawn(
.map_or(FileKind::Project, |repo| classify_file(repo, &file));
(file, kind)
});
let mut oplog_changed = false;
let (mut stripped_git_paths, mut worktree_relative_paths) =
(HashSet::new(), HashSet::new());
for (file_path, kind) in classified_file_paths {
match kind {
FileKind::ProjectIgnored => ignored += 1,
FileKind::GitUninteresting => git_noop += 1,
FileKind::GitButlerOplog => {
oplog_changed = true;
}
FileKind::Project | FileKind::Git => match file_path
.strip_prefix(&worktree_path)
{
@ -165,6 +170,13 @@ pub fn spawn(
break 'outer;
}
}
if oplog_changed {
let event = InternalEvent::GitButlerOplogChange(project_id);
if out.send(event).is_err() {
tracing::info!("channel closed - stopping file watcher");
break 'outer;
}
}
}
}
}
@ -201,6 +213,8 @@ enum FileKind {
Project,
/// A file that was ignored in the project, and thus shouldn't trigger a computation.
ProjectIgnored,
/// GitButler oplog file (`.git/gitbutler/operations-log.toml`)
GitButlerOplog,
}
fn classify_file(git_repo: &git::Repository, file_path: &Path) -> FileKind {
@ -212,6 +226,8 @@ fn classify_file(git_repo: &git::Repository, file_path: &Path) -> FileKind {
|| check_file_path == Path::new("index")
{
FileKind::Git
} else if check_file_path == Path::new("gitbutler").join(OPLOG_FILE_NAME) {
FileKind::GitButlerOplog
} else {
FileKind::GitUninteresting
}

View File

@ -60,6 +60,11 @@ impl Handler {
.await
.context("failed to handle git file change event"),
events::InternalEvent::GitButlerOplogChange(project_id) => self
.gitbutler_oplog_change(project_id)
.await
.context("failed to handle gitbutler oplog change event"),
// This is only produced at the end of mutating Tauri commands to trigger a fresh state being served to the UI.
events::InternalEvent::CalculateVirtualBranches(project_id) => self
.calculate_virtual_branches(project_id)
@ -181,4 +186,8 @@ impl Handler {
}
Ok(())
}
async fn gitbutler_oplog_change(&self, _project_id: ProjectId) -> Result<()> {
// TODO: Queue up pushing of data here, if configured
Ok(())
}
}