Skip to content

Adding FileLock #361

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

Merged
merged 5 commits into from
May 30, 2025
Merged

Adding FileLock #361

merged 5 commits into from
May 30, 2025

Conversation

roulpriya
Copy link
Contributor

@roulpriya roulpriya commented May 18, 2025

Fixes Issue #142

  • Description:
    Serialize concurrent swiftly install commands with a simple file lock.
    Adds a lightweight FileLock (using Data.write(to: fileURL, options: .withoutOverwriting)) and wraps the install routine so only one process installs at a time

@roulpriya roulpriya marked this pull request as draft May 19, 2025 05:11
@roulpriya roulpriya force-pushed the implement-filelock branch from e3cc983 to e55967c Compare May 19, 2025 12:31
@roulpriya roulpriya force-pushed the implement-filelock branch from 1ad88a3 to e5a6c8b Compare May 22, 2025 07:36
@roulpriya roulpriya marked this pull request as ready for review May 22, 2025 09:18
@cmcgee1024
Copy link
Member

@swift-ci test macOS

@roulpriya roulpriya force-pushed the implement-filelock branch from 48e6ef7 to b410967 Compare May 23, 2025 16:12
self.filePath = path
do {
let fileURL = URL(fileURLWithPath: self.filePath.string)
let contents = getpid().description.data(using: .utf8) ?? Data()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you use https://developer.apple.com/documentation/foundation/processinfo/processidentifier instead of getpid()? One fewer obstacle towards getting swiftly to work on Windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored @jakepetroules

@roulpriya roulpriya force-pushed the implement-filelock branch from b410967 to 689434a Compare May 26, 2025 14:09
@cmcgee1024
Copy link
Member

@swift-ci test macOS

@roulpriya roulpriya force-pushed the implement-filelock branch from ea8e37a to 858ec90 Compare May 26, 2025 14:54
@cmcgee1024
Copy link
Member

@swift-ci test macOS

@roulpriya roulpriya force-pushed the implement-filelock branch 3 times, most recently from 4359607 to 4ff4945 Compare May 28, 2025 10:31
@cmcgee1024
Copy link
Member

@swift-ci test macOS

var localizedDescription: String {
switch self {
case let .cannotAcquireLock(path):
return "Cannot acquire lock at \(path). Another process may be holding the lock."
Copy link
Member

Choose a reason for hiding this comment

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

suggestion (non-blocking): You can turn this into an actionable error by indicating that the user can remove the file if they are sure that there are no other processes running with the lock.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@roulpriya roulpriya force-pushed the implement-filelock branch 2 times, most recently from acb796a to f4c28a4 Compare May 29, 2025 11:06
@cmcgee1024
Copy link
Member

@swift-ci test macOS

var errorDescription: String? {
switch self {
case let .cannotAcquireLock(path):
return "Cannot acquire lock at \(path). Another process may be holding the lock. If you are sure no other processes are running, you can manually remove the lock file at \(path)."
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: The path is mentioned twice in the error message when it is probably only needed once.

}
}

// Timeout reached, throw an error
Copy link
Member

Choose a reason for hiding this comment

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

thought: This check to reconstruct the error may not be needed if you keep the last error, or use the Swift Result I linked above. It's fine as it is though.


@Suite struct FileLockTests {
@Test("FileLock creation writes process ID to lock file")
func testFileLockCreation() async throws {
Copy link
Member

@cmcgee1024 cmcgee1024 May 29, 2025

Choose a reason for hiding this comment

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

praise: These are really good unit tests: simple, and reliable. Sometimes lock testing tries to simulate race conditions, which can sacrifice reliability of the test.

Copy link
Member

@cmcgee1024 cmcgee1024 left a comment

Choose a reason for hiding this comment

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

Overall, this is looking really good and very nearly ready to be merged. There's just one blocking issue, and one language check override to do, and it should be done.

@roulpriya roulpriya force-pushed the implement-filelock branch from f4c28a4 to 20d1898 Compare May 30, 2025 07:00
@roulpriya roulpriya force-pushed the implement-filelock branch from 20d1898 to cdf027a Compare May 30, 2025 07:02
@cmcgee1024
Copy link
Member

@swift-ci test macOS

@cmcgee1024 cmcgee1024 merged commit fcb074e into swiftlang:main May 30, 2025
23 checks passed
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.

3 participants