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

Lock package directories with lock-files (fixes #957) #1116

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

emmabastas
Copy link

@emmabastas emmabastas commented Mar 25, 2025

Synopsis

This pull request fixes #957 using a very simple lock-file approach where the presence of a special .fpm-package-lock indicates that an fpm process is currently working on the package directory and that subsequent fpm processes should wait for the lock-file to be removed.

Checklist

  • There are unit-tests for the new module
  • There is documentation for the new module
  • All tests are passing on Linux+gfort and Windows+Mysys2+gfort, have not tested other setups.

Issues

  • I think it would be nice with some sort of integration-testing for this feature, but I haven't added that because I was unsure if it would be appropriate or not (as I understand there's only a unittesting setup right for fpm right now)
  • I wrote C functions that pass strings to Fortran and that was very painful for me to implement, and I cannot claim to understand what the precise differences between character(:), allocatable, character(len=1), pointer and type(c_ptr) are..

Implementation notes

The mere presence of .fpm-package-lock is enough for indicate a lock. This means that there are scenarios where a lock-file exists but there is no way of telling if the process that created it is still going or if it crashed. For this reason, if an fpm process sees that a lock-file exists already it prints an informative message to the user instructing them how to manually remove the lock if need be. (this is how git does it)

I went down the path of implementing a more "sophisticated" locking mechanism (see the https://github.com/emmabastas/fpm/tree/concurrent-invocations for my struggles x)) but I ended up concluding that it wouldn't be worth implementing. here's what I wrote in a comment in src/fpm_lock.f90 about that:

A common attempt at improving this situation might be to write the PID +
process start time into the lock-file, that way other processes can verify
that the lock-file wasn't left behind on accident. However this adds quite a
bit of complexity to the code, and it is very difficult / maybe even
impossible to do without race-conditions: There is no atomic way to tell the
OS to:

Open this file for reading with a shared lock in case it exists and
if it doesn't exists then create the file with for writing with an
exclusive lock.

Even if we we're able to do it there is a conceptual flaw: Distributed file
systems. If the package lives on another machine that you're accessing through
something like NFS then you'll end up writing your PID to a file living on
another machine that's not running the process, and so processes on that
machine can't know whether the lock is valid or not.

Now we might turn to actual OS file-locking primitives such as fcntl on UNIX
and LockFile on Windows. This is again a step-up in complexity, and I don't
know about LockFile but fcntl is fraught with problems:
https://chris.improbable.org/2010/12/16/everything-you-never-wanted-to-know-about-file-locking/

My conclusion is that anything more advanced than the current implementation
might just not be worth it, but I'm happy to be proven wrong! :-)

fixes fortran-lang#957

Squashed commit of the following:

commit 998ebba0c55cdd681e8575c1cc8d951e699c1907
Author: Emma Bastås <[email protected]>
Date:   Tue Mar 25 13:17:38 2025 +0100

    Remove nix flake

commit b35852a94fb3cb2444ed973b7f9c28b46964e93d
Author: Emma Bastås <[email protected]>
Date:   Tue Mar 25 13:09:34 2025 +0100

    Use fpm_lock in fpm commands

commit 0f72adccb1c4bdf4c9b49b6336b550fb705fb2f0
Author: Emma Bastås <[email protected]>
Date:   Tue Mar 25 11:40:27 2025 +0100

    Better unitest fixtures

commit 49dbf5e2d4ace90b98dda959f903af41b42f94ed
Author: Emma Bastås <[email protected]>
Date:   Mon Mar 24 18:48:55 2025 +0100

    Fix memory issues

commit 45d8b1454d99277fad78fb26def34773d41d01b0
Author: Emma Bastås <[email protected]>
Date:   Mon Mar 24 16:39:59 2025 +0100

    Fix a typo

commit 0d86b10c76b6594d7363e6b2b697b08c9eccb92d
Author: Emma Bastås <[email protected]>
Date:   Mon Mar 24 16:39:31 2025 +0100

    Add implementation notes

commit b90dad7fdbd0c9c66700732c5af0f5919bb0ea64
Author: Emma Bastås <[email protected]>
Date:   Mon Mar 24 16:16:14 2025 +0100

    Remove lock-files with atexit

commit 4b6fea47f3771e280f89538f5435cb6e2b510b19
Author: Emma Bastås <[email protected]>
Date:   Sun Mar 23 16:20:13 2025 +0100

    Simplify logic

commit 66ff71676e3b8f5f744b146d9f6515e16c1b83fe
Author: Emma Bastås <[email protected]>
Date:   Fri Mar 21 15:49:02 2025 +0100

    All tests pass on Linux and Windows!!

commit 019ffc96ee4c9b0d388271543ff295a77eebd192
Author: Emma Bastås <[email protected]>
Date:   Fri Mar 21 15:42:57 2025 +0100

    Almost everthing works

commit b7e2c1af4589a427e925fb98068cecf598cb2366
Author: Emma Bastås <[email protected]>
Date:   Fri Mar 21 11:54:29 2025 +0100

    Implement for Windows.

commit 588fcf7f5674dfd92b9bfd485222f71ca1e49db0
Author: Emma Bastås <[email protected]>
Date:   Fri Mar 21 11:54:00 2025 +0100

    Kill processes without resorting to C.

commit 688a38d5e7076fb1f71cbd33fe828691058d3443
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 20:08:17 2025 +0100

    More documentation and comments

commit f39ef3ef5ca498920212c1470808cef6ee385032
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 18:03:10 2025 +0100

    Handle more errors properly

commit b831f652b26166e7f2c124ec9634214f0fb3b527
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 17:13:05 2025 +0100

    Add a unit test

commit fd7ffb8f5e8d76bb60545c79ac3c0a14c8dd4abd
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 17:00:27 2025 +0100

    Reap child process after kill

commit 6f12e87f7d9a92e10efc51922b3d6ba27646c85a
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 17:00:11 2025 +0100

    Change some comments

commit 757300003dacc095724885ccbedb2a5f98006b9e
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 16:59:54 2025 +0100

    Implement a process_alive function

commit 26eb598ab124c338e38751a61bf5a8c21a412a21
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 15:02:36 2025 +0100

    Fail test early if package-locking fails

commit 107dcec984d3a34b7dc340e82f189b30acdf27f2
Author: Emma Bastås <[email protected]>
Date:   Wed Mar 19 14:56:32 2025 +0100

    Make it better

commit 82e9224c458ad899660ed94866c87161cde8111c
Author: Emma Bastås <[email protected]>
Date:   Sat Mar 15 17:59:40 2025 +0100

    Add tests

commit e1169ca897df690309941d83872447515656234d
Author: Emma Bastås <[email protected]>
Date:   Sat Mar 15 17:58:04 2025 +0100

    WIP: Pid in lock-file + error handling

commit 903ec6fc758d50944a95acdf10a7bc7237ed5834
Author: Emma Bastås <[email protected]>
Date:   Sat Mar 1 18:59:32 2025 +0100

    Start work on package locking

commit 65f0905a4ed6f043eaabdb2d08bfd4f9654e161e
Author: Emma Bastås <[email protected]>
Date:   Sat Mar 1 13:42:46 2025 +0100

    TODO: Remove. nix dev enviroment
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.

Safely handle parallel/concurrent invocations
1 participant