Skip to content
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

feat: Add Repository::lock_repo #163

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

feat: Add Repository::lock_repo #163

wants to merge 3 commits into from

Conversation

aawsome
Copy link
Member

@aawsome aawsome commented Feb 16, 2024

Adds Repository::lock_repo which locks all repository files. Also the backend trait is extended to support locking and a lock_command has been added to RepositoryOptions which turns any backend into a backend capable of locking.

see rustic-rs/rustic#1050

Missing points:

  • Add unit tests

@aawsome aawsome changed the title Add lock command feat(commands): Add lock command Feb 16, 2024
@aawsome aawsome changed the title feat(commands): Add lock command feat(commands)!: Add lock command Sep 7, 2024
Copy link

codecov bot commented Sep 27, 2024

@aawsome aawsome force-pushed the lock branch 3 times, most recently from bed411c to 14488d4 Compare October 5, 2024 06:28
@aawsome aawsome changed the title feat(commands)!: Add lock command feat(commands): Add lock command Oct 5, 2024
@aawsome aawsome changed the title feat(commands): Add lock command feat: Add Repository::lock_repository Oct 5, 2024
@aawsome aawsome changed the title feat: Add Repository::lock_repository feat: Add Repository::lock_repo Oct 5, 2024
Comment on lines 359 to 362
fn lock(&self, tpe: FileType, id: &Id, until: Option<DateTime<Local>>) -> Result<()> {
debug!("no locking implemented. {tpe:?}, {id}, {until:?}");
Ok(())
}
Copy link
Contributor

@simonsan simonsan Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check here for ::can_lock() and if that is true and ::lock() is being called in the default implementation, I would panic!() or unimplemented!("no locking implemented") as otherwise someone could actually think, they can use this and won't reimplement it. It should definitely not silently continue here.

if self.can_lock() {
   unimplemented!("no locking implemented");
} 

Copy link
Contributor

@simonsan simonsan Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Especially because it doesn't implement the expected behaviour.

e.g. how axum does it: https://github.com/tokio-rs/axum/releases/tag/axum-v0.8.0-alpha.1

breaking: Upgrade matchit to 0.8, changing the path parameter syntax from /:single and /*many to /{single} and /{*many}; the old syntax produces a panic to avoid silent change in behavior (#2645)

crates/core/src/commands.rs Show resolved Hide resolved
crates/core/src/backend/lock.rs Outdated Show resolved Hide resolved
true
}

fn lock(&self, tpe: FileType, id: &Id, until: Option<DateTime<Local>>) -> Result<()> {
Copy link
Contributor

@simonsan simonsan Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

::lock() should never be callable/running its body, if ::can_lock() isn't returning true, I think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A type state design might be better suited here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we do have a problem with the type state pattern here: The Repository traits need to be object save as we do create dynamic trait objects here.
Do you know a way to implement a type state pattern in combination with object safety?

Comment on lines +36 to +39
if !repo.be.can_lock() {
return Err(CommandErrorKind::NoLockingConfigured.into());
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we check that here, but I think this should be checked within the ::lock() itself, so people using it, can't forget to call it.

Comment on lines 65 to 68
if let Err(e) = backend.lock(ID::TYPE, id, until) {
// FIXME: Use error handling
error!("lock failed for {:?} {id:?}. {e}", ID::TYPE);
};
Copy link
Contributor

@simonsan simonsan Oct 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually enough to just log an error here? If something like that lock can't be acquired, I would throw an error actually, so the command is not being run, right? The expectation on a function, that is called lock_files should be that is errors out, when it can't lock the files, and not just logs an error I feel.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same error handling discussion as in many places: The best would here to log an error, continue and collect the errors and at the end fail with the list of errors...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :/ But keeping it running and not failing early also opens room up for possible bugs I think that could affect repository integrity? (in general, not regarding the locking discussion).

When you say at the end, what do you mean by that. Just in the end of the program's run? Or at the end of the function?

Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
@simonsan
Copy link
Contributor

simonsan commented Oct 6, 2024

I pushed some of my proposed changes in a commit, to better explain what I mean. I'm not so sure about the design between can_lock() and lock(), that needs to check itself, if can_lock() is true before running. This makes probably some room for bugs, if someone forgets to check it before running lock() - so not sure about the API design in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants