Haskell: openFile for multiple handles (W+R+R+R…) w/o “file is locked”
I am working on file-backed queue in Haskell (pub/sub + storage).
My idea is to have a log file with W+R+R+R handles to it:
- pub: one W handle, for writing/appending
- sub: multiple R for tailing and random seeking to past entries
However, opening two handles (R+W) to the same file doesn't work with GHC:
#!/usr/bin/env stack
-- stack --resolver lts-13.0 --install-ghc runghc
module Main where
import System.IO
main :: IO ()
main = do
let path = "file.txt"
_ <- openFile path WriteMode
_ <- openFile path ReadMode -- throws *** Exception: file.txt: openFile: resource busy (file is locked)
_ <- openFile path ReadMode
_ <- openFile path ReadMode
return ()
File locking section starts promising:
Implementations should enforce as far as possible, at least locally to
the Haskell process, multiple-reader single-writer locking on files.
... but then says:
That is, there may either be many handles on the same file which
manage input, or just one handle on the file which manages output.
Questions:
- why is there such limitation?
- how to have W+R+R+R handles to a file in Haskell/GHC?
haskell locking
add a comment |
I am working on file-backed queue in Haskell (pub/sub + storage).
My idea is to have a log file with W+R+R+R handles to it:
- pub: one W handle, for writing/appending
- sub: multiple R for tailing and random seeking to past entries
However, opening two handles (R+W) to the same file doesn't work with GHC:
#!/usr/bin/env stack
-- stack --resolver lts-13.0 --install-ghc runghc
module Main where
import System.IO
main :: IO ()
main = do
let path = "file.txt"
_ <- openFile path WriteMode
_ <- openFile path ReadMode -- throws *** Exception: file.txt: openFile: resource busy (file is locked)
_ <- openFile path ReadMode
_ <- openFile path ReadMode
return ()
File locking section starts promising:
Implementations should enforce as far as possible, at least locally to
the Haskell process, multiple-reader single-writer locking on files.
... but then says:
That is, there may either be many handles on the same file which
manage input, or just one handle on the file which manages output.
Questions:
- why is there such limitation?
- how to have W+R+R+R handles to a file in Haskell/GHC?
haskell locking
2
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
2
Maybe an alternative is to go low-level, useSystem.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.
– chi
Dec 30 '18 at 21:35
1
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
1
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13
add a comment |
I am working on file-backed queue in Haskell (pub/sub + storage).
My idea is to have a log file with W+R+R+R handles to it:
- pub: one W handle, for writing/appending
- sub: multiple R for tailing and random seeking to past entries
However, opening two handles (R+W) to the same file doesn't work with GHC:
#!/usr/bin/env stack
-- stack --resolver lts-13.0 --install-ghc runghc
module Main where
import System.IO
main :: IO ()
main = do
let path = "file.txt"
_ <- openFile path WriteMode
_ <- openFile path ReadMode -- throws *** Exception: file.txt: openFile: resource busy (file is locked)
_ <- openFile path ReadMode
_ <- openFile path ReadMode
return ()
File locking section starts promising:
Implementations should enforce as far as possible, at least locally to
the Haskell process, multiple-reader single-writer locking on files.
... but then says:
That is, there may either be many handles on the same file which
manage input, or just one handle on the file which manages output.
Questions:
- why is there such limitation?
- how to have W+R+R+R handles to a file in Haskell/GHC?
haskell locking
I am working on file-backed queue in Haskell (pub/sub + storage).
My idea is to have a log file with W+R+R+R handles to it:
- pub: one W handle, for writing/appending
- sub: multiple R for tailing and random seeking to past entries
However, opening two handles (R+W) to the same file doesn't work with GHC:
#!/usr/bin/env stack
-- stack --resolver lts-13.0 --install-ghc runghc
module Main where
import System.IO
main :: IO ()
main = do
let path = "file.txt"
_ <- openFile path WriteMode
_ <- openFile path ReadMode -- throws *** Exception: file.txt: openFile: resource busy (file is locked)
_ <- openFile path ReadMode
_ <- openFile path ReadMode
return ()
File locking section starts promising:
Implementations should enforce as far as possible, at least locally to
the Haskell process, multiple-reader single-writer locking on files.
... but then says:
That is, there may either be many handles on the same file which
manage input, or just one handle on the file which manages output.
Questions:
- why is there such limitation?
- how to have W+R+R+R handles to a file in Haskell/GHC?
haskell locking
haskell locking
edited Dec 31 '18 at 3:14
oshyshko
asked Dec 30 '18 at 14:49
oshyshkooshyshko
1,01721527
1,01721527
2
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
2
Maybe an alternative is to go low-level, useSystem.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.
– chi
Dec 30 '18 at 21:35
1
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
1
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13
add a comment |
2
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
2
Maybe an alternative is to go low-level, useSystem.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.
– chi
Dec 30 '18 at 21:35
1
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
1
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13
2
2
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
2
2
Maybe an alternative is to go low-level, use
System.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.– chi
Dec 30 '18 at 21:35
Maybe an alternative is to go low-level, use
System.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.– chi
Dec 30 '18 at 21:35
1
1
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
1
1
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53978597%2fhaskell-openfile-for-multiple-handles-wrrr-w-o-file-is-locked%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53978597%2fhaskell-openfile-for-multiple-handles-wrrr-w-o-file-is-locked%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
That's a direct quote from the Haskell Report. Personally, I disagree with that requirement. I guess it was added to force programmers to write portable code, which would run even on OSs where such locking was mandatory. I don't know of any OS which enforces that today: even windows allows a process to open a file in a shared mode (multiple readers and multiple writers).
– chi
Dec 30 '18 at 16:00
If you don't need to be portable, you could do a work around by hard linking a set of files.
– luqui
Dec 30 '18 at 16:37
2
Maybe an alternative is to go low-level, use
System.Posix.IO
to open the file multiple times, creating FDs, and then turn those into handles. Assuming posix, of course.– chi
Dec 30 '18 at 21:35
1
@chi unfortunately calling fdToHandle on first R fd throws the same "locked" exception
– oshyshko
Dec 31 '18 at 3:20
1
gist.github.com/oshyshko/b6728f34903e1458100dda3d095f92ca - my best attempt so far. It works, but is not pretty, not efficient and uses Fd instead of Handle
– oshyshko
Dec 31 '18 at 7:13