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

Error with RTS option --io-manager=native in Pantry.Storage.initStorage #59

Open
mpilgrem opened this issue Sep 6, 2022 · 2 comments
Open

Comments

@mpilgrem
Copy link
Member

mpilgrem commented Sep 6, 2022

Issue first raised in Stack repository, see commercialhaskell/stack#5851. The suggested workaround in the exception message is not a workaround.

On Windows, the command stack build +RTS --io-manager=native -RTS results in the display of the MigrationFailure PantryException

Encountered error while migrating Pantry database:
    \\.\NUL: hDuplicateTo: illegal operation (handles are incompatible)
Please report this on https://github.com/commercialhaskell/stack/issues
As a workaround you may delete Pantry database in C:\sr\pantry\pantry.sqlite3 triggering its recreation.

This is arising from the Pantry.Storage.initStorage (a wrapper around Pantry.Storage.SQLite.initStorage) in Pantry.withPantryConfig. (Stack uses withPantryConfig in Stack.Config.configFromConfigMonoid.) I am still investigating.

@mpilgrem
Copy link
Member Author

mpilgrem commented Sep 6, 2022

Pantry.SQLite.initStorage includes:

migrates <- withWriteLock (display description) fp $ wrapMigrationFailure $
    withSqliteConnInfo (sqinfo True) $ runSqlConn $
    runMigrationSilent migration

If that is changed to:

  migrates <- withWriteLock (display description) fp $ wrapMigrationFailure $
    withSqliteConnInfo (sqinfo True) $ runSqlConn $ do
      runMigration migration

the issue disappears. Now, Database.Persist.Sql.Migration.runMigrationSilent is:

runMigrationSilent :: MonadUnliftIO m
                   => Migration
                   -> ReaderT SqlBackend m [Text]
runMigrationSilent m = withRunInIO $ \run ->
  hSilence [stderr] $ run $ runMigration' m True

System.IO.Silently.hSilence, from the silently package, has:

mNullDevice :: Maybe FilePath
#ifdef WINDOWS
mNullDevice = Just "\\\\.\\NUL"
#elif UNIX
mNullDevice = Just "/dev/null"
#else
mNullDevice = Nothing
#endif

-- | Run an IO action while preventing all output to the given handles.
hSilence :: forall a. [Handle] -> IO a -> IO a
hSilence handles action =
  case mNullDevice of
    Just nullDevice ->
      E.bracket (openFile nullDevice AppendMode)
                hClose
                prepareAndRun
    Nothing -> withTempFile "silence" prepareAndRun
  where
    prepareAndRun :: Handle -> IO a
    prepareAndRun tmpHandle = go handles
      where
        go []     = action
        go (h:hs) = goBracket go tmpHandle h hs

goBracket :: ([Handle] -> IO a) -> Handle -> Handle -> [Handle] -> IO a
goBracket go tmpHandle h hs = do
  buffering <- hGetBuffering h
  let redirect = do
        old <- hDuplicate h
        hDuplicateTo tmpHandle h
        return old
      restore old = do
        hDuplicateTo old h
        hSetBuffering h buffering
        hClose old
  E.bracket redirect restore (\_ -> go hs)

@mpilgrem
Copy link
Member Author

mpilgrem commented Sep 6, 2022

I think this is an upstream issue. See yesodweb/persistent#1423 and GHC issue #22146.

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

No branches or pull requests

1 participant