-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#7 と #60 の実装について意見を伺いたい #65
Conversation
PRありがとう、説明をサボったままお願いしてしまって本当に申し訳ないです。 #[test]
fn drop_not_leaf_node() -> anyhow::Result<()> {
let a = TextFile::new(PathBuf::from("a.txt"), "hello!".to_string())?;
let b = a.create_symlink_to(PathBuf::from("b.txt"))?;
let c = b.create_symlink_to(PathBuf::from("c.txt"))?;
std::mem::drop(b);
println!("b is dropped.");
Ok(())
}
/*
output:
b1 is dropped.
"c.txt"
"b.txt"
"a.txt"
expected:
"b.txt"
b1 is dropped.
"c.txt"
"a.txt"
*/ これは、今は木構造が
になっているからcがdropするまでbがdropしないからで、辺を
のように貼って、a,b,cそれぞれがArc<Lock>を持つようにすれば、木構造を壊さずに適時ファイルが消えるようになるしdropも各ファイルの実体に対して必ず1回走るようになる気がします。
になると思います。 |
レビューありがとう,根に直接リンクを繋ぐのが素直そうですね,その方針で実装してみたいと思います 👍 |
@comavius Link が Arc<Entity 全体> を持つと Link から drop されることが保証されていそうですが,Link が Arc<Entity の中にある Lock> を持つと Link から drop されることが保証されないような気がしています(そもそも Lock は Entity のフィールドにあるという認識で合っていますか). もし Link が Arc<Entity 全体> を持たないといけないとなると,初めに述べたような状況になってしまいそうで難しいです.何か良い方法がないか(そもそも認識が合っているか)を伺いたいです. |
struct Link {
entity: Arc<RwLock<Entity>>,
//...
} であれば、 |
それだと動作すると思います.ただ,どこかで (たとえば初めに示した実装だと |
@comavius struct Entity {
path: PathBuf,
}
impl File for Entity {
type InitArgs = String;
type Link = Link;
fn new(path: PathBuf, args: Self::InitArgs) -> anyhow::Result<Self> {
// ここでファイル作成する
Ok(Entity { path })
}
fn create_symlink_to(&self, path: PathBuf) -> anyhow::Result<Self::Link> {
Link::new(
path,
unimplemented!("ここで Arc<RwLock<Entity>> の clone を渡したいが,どこから持ってくればよいのかわからない."),
)
}
}
struct Link {
path: PathBuf,
entity: Arc<RwLock<Entity>>,
}
impl File for Link {
type InitArgs = Arc<RwLock<Entity>>;
type Link = Link;
fn new(path: PathBuf, args: Self::InitArgs) -> anyhow::Result<Self> {
// ここでシンボリックリンク作成する
Ok(Link {
path,
entity: args.clone(),
})
}
fn create_symlink_to(&self, path: PathBuf) -> anyhow::Result<Self::Link> {
Link::new(path, self.entity.clone())
}
} |
@hayatroid |
8e6a87b
to
3fdbea3
Compare
@comavius #[test]
fn drop_not_leaf_node() -> anyhow::Result<()> {
let a = Arc::new(RwLock::new(TextFileEntity::new(
PathBuf::from("a.txt"),
"hello".to_string(),
)?));
let b = TextFileLink::new(PathBuf::from("b.txt"), a.clone())?;
let c = b.create_symlink_to(PathBuf::from("c.txt"))?;
drop(b);
println!("b is dropped.");
Ok(())
} これの出力は
となり,要件を満たしていると思います. よさそうだったらデバッグ出力を消して, |
@hayatroid もう一点、 |
関連Issue
概要
意見を伺いたいです.
#7 と #60 を実現するため,以下のように
text_file.rs
の実装をしました.ファイルの依存関係を,オリジナルファイルを根,シンボリックリンクのリンク先を親,リンク元を子とした根付き木として考えたときに,
TextFileInner
と,これをArc
でラップしたTextFile
の 2 つの構造体を用意した.tests.rs
を書いて正しく動作していそうなことを確認した.RwLock<FileAccess>
を共有するため,Arc<RwLock<FileAccess>>
を作成して持たせ,子孫にこれの clone を持たせた.しかし,以下の状況に直面しました.
create_symlink_to
とdrop
とでどちらの構造体に実装したいかが異なる.create_symlink_to
はself.clone()
を子に持たせるためにArc
でラップされたTextFile
側に実装したい.drop
は 1 ファイルに 1 回だけ呼び出されるようにArc
でラップされていないTextFileInner
側に実装したい.トレイトを書き換えれば解決することではありますが,
Arc
周りの理解が浅くあまり自身がないです)など意見を伺いたいです.よろしくお願いします.