Haskell: openFile for multiple handles (W+R+R+R…) w/o “file is locked”












5















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?










share|improve this question




















  • 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
















5















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?










share|improve this question




















  • 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














5












5








5


2






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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, 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














  • 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








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












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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas