From 2f08a0a28c888d6227cd50f26225b3660c9b78ad Mon Sep 17 00:00:00 2001 From: TheCub3 <33991163+SultanTanirkul@users.noreply.github.com> Date: Mon, 26 Aug 2024 21:40:20 +0500 Subject: [PATCH] Fix fifo files hanging the project wide search (#16039) Release Notes: - Fixed the issue related to the project wide search being stuck when project contains .fifo files - Might potentially solve the following issue https://github.com/zed-industries/zed/issues/7360 --- .../20221109000000_test_schema.sql | 1 + ...240823155956_add_is_fifo_to_worktree_entries.sql | 2 ++ crates/collab/src/db/queries/projects.rs | 2 ++ crates/collab/src/db/queries/rooms.rs | 1 + crates/collab/src/db/tables/worktree_entry.rs | 1 + crates/fs/src/fs.rs | 13 +++++++++++++ crates/project/src/project.rs | 11 ++++++++--- crates/project_panel/src/project_panel.rs | 1 + crates/proto/proto/zed.proto | 1 + crates/worktree/src/worktree.rs | 4 ++++ 10 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 crates/collab/migrations/20240823155956_add_is_fifo_to_worktree_entries.sql diff --git a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql index 4db9774c23..5c2c396160 100644 --- a/crates/collab/migrations.sqlite/20221109000000_test_schema.sql +++ b/crates/collab/migrations.sqlite/20221109000000_test_schema.sql @@ -86,6 +86,7 @@ CREATE TABLE "worktree_entries" ( "is_ignored" BOOL NOT NULL, "is_deleted" BOOL NOT NULL, "git_status" INTEGER, + "is_fifo" BOOL NOT NULL, PRIMARY KEY(project_id, worktree_id, id), FOREIGN KEY(project_id, worktree_id) REFERENCES worktrees (project_id, id) ON DELETE CASCADE ); diff --git a/crates/collab/migrations/20240823155956_add_is_fifo_to_worktree_entries.sql b/crates/collab/migrations/20240823155956_add_is_fifo_to_worktree_entries.sql new file mode 100644 index 0000000000..af6fdac19d --- /dev/null +++ b/crates/collab/migrations/20240823155956_add_is_fifo_to_worktree_entries.sql @@ -0,0 +1,2 @@ +ALTER TABLE "worktree_entries" +ADD "is_fifo" BOOL NOT NULL DEFAULT FALSE; diff --git a/crates/collab/src/db/queries/projects.rs b/crates/collab/src/db/queries/projects.rs index 1bf729c35e..a6956c8496 100644 --- a/crates/collab/src/db/queries/projects.rs +++ b/crates/collab/src/db/queries/projects.rs @@ -319,6 +319,7 @@ impl Database { git_status: ActiveValue::set(entry.git_status.map(|status| status as i64)), is_deleted: ActiveValue::set(false), scan_id: ActiveValue::set(update.scan_id as i64), + is_fifo: ActiveValue::set(entry.is_fifo), } })) .on_conflict( @@ -727,6 +728,7 @@ impl Database { is_ignored: db_entry.is_ignored, is_external: db_entry.is_external, git_status: db_entry.git_status.map(|status| status as i32), + is_fifo: db_entry.is_fifo, }); } } diff --git a/crates/collab/src/db/queries/rooms.rs b/crates/collab/src/db/queries/rooms.rs index 185bcf7b36..34d6d63ab7 100644 --- a/crates/collab/src/db/queries/rooms.rs +++ b/crates/collab/src/db/queries/rooms.rs @@ -663,6 +663,7 @@ impl Database { is_ignored: db_entry.is_ignored, is_external: db_entry.is_external, git_status: db_entry.git_status.map(|status| status as i32), + is_fifo: db_entry.is_fifo, }); } } diff --git a/crates/collab/src/db/tables/worktree_entry.rs b/crates/collab/src/db/tables/worktree_entry.rs index 81bf6e2d53..d60d2c336b 100644 --- a/crates/collab/src/db/tables/worktree_entry.rs +++ b/crates/collab/src/db/tables/worktree_entry.rs @@ -21,6 +21,7 @@ pub struct Model { pub is_external: bool, pub is_deleted: bool, pub scan_id: i64, + pub is_fifo: bool, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 7635da0017..804d029c98 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -9,6 +9,9 @@ use std::{fs::File, os::fd::AsFd}; #[cfg(unix)] use std::os::unix::fs::MetadataExt; +#[cfg(unix)] +use std::os::unix::fs::FileTypeExt; + use async_tar::Archive; use futures::{future::BoxFuture, AsyncRead, Stream, StreamExt}; use git::repository::{GitRepository, RealGitRepository}; @@ -149,6 +152,7 @@ pub struct Metadata { pub mtime: SystemTime, pub is_symlink: bool, pub is_dir: bool, + pub is_fifo: bool, } #[derive(Default)] @@ -428,11 +432,18 @@ impl Fs for RealFs { #[cfg(windows)] let inode = file_id(path).await?; + #[cfg(windows)] + let is_fifo = false; + + #[cfg(unix)] + let is_fifo = metadata.file_type().is_fifo(); + Ok(Some(Metadata { inode, mtime: metadata.modified().unwrap(), is_symlink, is_dir: metadata.file_type().is_dir(), + is_fifo, })) } @@ -1537,12 +1548,14 @@ impl Fs for FakeFs { mtime: *mtime, is_dir: false, is_symlink, + is_fifo: false, }, FakeFsEntry::Dir { inode, mtime, .. } => Metadata { inode: *inode, mtime: *mtime, is_dir: true, is_symlink, + is_fifo: false, }, FakeFsEntry::Symlink { .. } => unreachable!(), })) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index cf52396019..81a9169227 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -10969,10 +10969,15 @@ async fn search_snapshots( abs_path.clear(); abs_path.push(&snapshot.abs_path()); abs_path.push(&entry.path); - if let Some(file) = fs.open_sync(&abs_path).await.log_err() { - query.detect(file).unwrap_or(false) - } else { + + if entry.is_fifo { false + } else { + if let Some(file) = fs.open_sync(&abs_path).await.log_err() { + query.detect(file).unwrap_or(false) + } else { + false + } } } else { false diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index a9849bb583..f1f9034a10 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1678,6 +1678,7 @@ impl ProjectPanel { canonical_path: entry.canonical_path.clone(), is_symlink: entry.is_symlink, char_bag: entry.char_bag, + is_fifo: entry.is_fifo, }); } if expanded_dir_ids.binary_search(&entry.id).is_err() diff --git a/crates/proto/proto/zed.proto b/crates/proto/proto/zed.proto index 1de83748c2..13a20adaa7 100644 --- a/crates/proto/proto/zed.proto +++ b/crates/proto/proto/zed.proto @@ -1814,6 +1814,7 @@ message Entry { bool is_ignored = 7; bool is_external = 8; optional GitStatus git_status = 9; + bool is_fifo = 10; } message RepositoryEntry { diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 5485acb008..fecfdb11fe 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -3186,6 +3186,7 @@ pub struct Entry { /// Whether this entry is considered to be a `.env` file. pub is_private: bool, pub char_bag: CharBag, + pub is_fifo: bool, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -3246,6 +3247,7 @@ impl Entry { is_private: false, git_status: None, char_bag, + is_fifo: metadata.is_fifo, } } @@ -5106,6 +5108,7 @@ impl<'a> From<&'a Entry> for proto::Entry { is_ignored: entry.is_ignored, is_external: entry.is_external, git_status: entry.git_status.map(git_status_to_proto), + is_fifo: entry.is_fifo, } } } @@ -5134,6 +5137,7 @@ impl<'a> TryFrom<(&'a CharBag, proto::Entry)> for Entry { is_private: false, is_symlink: entry.is_symlink, char_bag, + is_fifo: entry.is_fifo, }) } }