GithubHelp home page GithubHelp logo

unliftio's People

Contributors

amesgen avatar bitonic avatar brandon-leapyear avatar brandonchinn178 avatar centromere avatar danburton avatar effectfully avatar epoberezkin avatar evanrelf avatar fumieval avatar geekingfrog avatar ivanbakel avatar koterpillar avatar lehins avatar matthewbauer avatar mbwgh avatar mgsloan avatar mitchellwrosen avatar nickkuk avatar nshimaza avatar ntc2 avatar ocharles avatar parsonsmatt avatar psibi avatar roman avatar smarthypercube avatar snoyberg avatar steffahn avatar tbidne avatar terrorjack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

unliftio's Issues

Unify `UnliftIO.Handler` and `Control.Monad.Catch.Handler`

The definitions for Handler in both of these libraries appear to be the same.

exceptions Handler:

-- | Generalized version of 'ControlException.Handler'
data Handler m a = forall e . ControlException.Exception e => Handler (e -> m a)

unliftio Handler

-- | A helper data type for usage with 'catches' and similar functions.
--
-- @since 0.1.0.0
data Handler m a = forall e . Exception e => Handler (e -> m a)

This would require depending on exceptions, or an as-of-yet-unreleased package that factors the generalized Handler out.

The RIO monad.

Let me keep discussion around the RIO monad aproach.

I've already used monad RIO a lot in my commercial GUI application that is based on sdl2 and reactive-banana libraries and targets to Windows-Linux desktops and ARM embedded; it must be fast, responsive and robust as it works 24/7 on this sensor stand.

At now I use the following module:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module UnliftIO.MonadRIO where

import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Reader (MonadReader, ReaderT (ReaderT))
import Control.Monad.Trans.Resource (MonadResource, liftResourceT, MonadThrow, ResourceT,
                                     InternalState, runInternalState, withInternalState)
import Control.Monad.Base (MonadBase)
import Control.Lens (Lens', view)
import UnliftIO (MonadUnliftIO)

newtype RIO env a = RIO { unRIO :: ReaderT env IO a }
  deriving (Functor, Applicative, Monad, MonadIO, MonadReader env,
            MonadThrow, MonadBase IO, MonadUnliftIO)

{-# INLINE runRIO #-}
runRIO :: MonadIO m => env -> RIO env a -> m a
runRIO env (RIO (ReaderT f)) = liftIO (f env)

instance HasResources env => MonadResource (RIO env) where
  {-# INLINE liftResourceT #-}
  liftResourceT resT = view resourcesL >>= liftIO . runResources resT

newtype Resources = Resources InternalState

{-# INLINE runResources #-}
runResources :: ResourceT m a -> Resources -> m a
runResources action (Resources intState) = runInternalState action intState

{-# INLINE withResources #-}
withResources :: (Resources -> m a) -> ResourceT m a
withResources action = withInternalState (action . Resources)

class HasResources env where
  resourcesL :: Lens' env Resources

instance HasResources Resources where
  {-# INLINE resourcesL #-}
  resourcesL = id

UnliftIO.Exception gives me capabilities of safe-exceptions and lifted-base, UnliftIO.Async gives safe lifted async; also I've added #5 to get almost full (and in the same time safer) strength of lifted-base.

In this issue I want to discuss

  1. the possibility to add the RIO monad to unliftio-core or unliftio or anywhere else;
  2. interaction of the RIO monad with ResourceT - at now I use lens and instance HasResources env => MonadResource (RIO env);
  3. interaction with monad-logger.

Bug: docs should be louder about changed async exception semantics

The mostly great overview documentation for the unliftio library waits until page 7 to mention that the library changes the semantics of async exceptions. Since the main unlifting concept is easy to understand from the examples, and is orthogonal to changing async exception semantics, I expect many people don't read all the way to the end and never imagine the library would also change async semantics. Some of those people (me) will then spend hours debugging subtle problems related to the changed async exception semantics. I propose that the documentation make it loud and clear, from the beginning, that the library changes async exception semantics and is not simply a drop in generalization of Control.Exception when it comes to exceptions.

The "Quickstart" on the first page of the docs does say "Replace imports like Control.Exception with UnliftIO.Exception. Yay, your catch and finally are more powerful and safer!", with "safer" here hinting at the changed semantics, but I don't think that's going to help anyone who doesn't already know that unliftio takes the safe-exceptions approach. In fact, the docs even give an example of implementing an unliftio version of mask, which is one of the exception-related functions that does not change async semantics, encouraging further confusion.

Because the unlifting is orthogonal to the safe exceptions, I suppose the best approach would be to make the safe exceptions opt-in, by making two versions of the library, say unliftio-traditional-exceptions and unliftio-safe-exceptions; might be a nice use for backpack when it's mature.

add createFileLink

I guess unliftio goal is to rexexport System.Directory functions with lifted IO monad.
I noticed that createFileLink is not provided.
Is it exported from other place? IMHO the function name doesn't fit well into the origin namespace, does it?

Should timeout/race forcibly unmask async exceptions?

timeout and race use async exceptions to cancel a timed-out action. IMO, the fact that these use async exceptions are an implementation detail, so I would think the user shouldn't have to care about the fact that these use async exceptions.

For example, if someone were to do

action `finally` timeout (60 * 1000000) cleanup

I think the user would be surprised that it doesn't timeout.

file-posix.c build error

Building a project that includes unliftio (Stackage LTS 14.27 i.e. GHC 8.6.5) fails with this:

unliftio      > [20 of 20] Compiling UnliftIO
unliftio      > 
unliftio      > /private/var/folders/n0/zx3dkw3d2hd3x59rjk3gtj5r0000gn/T/stack24793/unliftio-0.2.12/cbits/file-posix.c:16:10: error:
unliftio      >      error: use of undeclared identifier 'AT_FDCWD'
unliftio      >       return AT_FDCWD;
unliftio      >              ^
unliftio      >    |
unliftio      > 16 |   return AT_FDCWD;
unliftio      >    |          ^
unliftio      > 
unliftio      > /private/var/folders/n0/zx3dkw3d2hd3x59rjk3gtj5r0000gn/T/stack24793/unliftio-0.2.12/cbits/file-posix.c:21:10: error:
unliftio      >      error: use of undeclared identifier 'AT_SYMLINK_FOLLOW'
unliftio      >       return AT_SYMLINK_FOLLOW;
unliftio      >              ^
unliftio      >    |
unliftio      > 21 |   return AT_SYMLINK_FOLLOW;
unliftio      >    |          ^
unliftio      > 2 errors generated.
unliftio      > `gcc' failed in phase `C Compiler'. (Exit code: 1)

If it helps,

$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

Hang in `withSystemTempDirectory`

This is a bit of a weird one... apologies that I can't provide more information.

I'm seeing hangs in withSystemTempDirectory where the CPU remains pegged at 100%.
Unfortunately, I haven't been able to reproduce using a small program, so if possible I'd like advice on how to debug further.

I've got an strace snippet from the call to withSystemTempDirectory:

stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=760, ...}) = 0
lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=760, ...}) = 0
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]})                 = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]})                 = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]})                 = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]})                 = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]})                 = 1
[...]
timer_settime(0, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=0}}, NULL) = 0
rt_sigreturn({mask=[]})                 = 1

AFAICT the SIGVTALRM stuff is from the GHC RTS and not really related to withSystemTempDirecotry.

Any ideas on how to get more debug info that could be of use tracking this down? The problem doesn't reproduce when I try a trivial "main".

(Aside: Would it not be better to use a random number instead of the PID when choosing candidate file names? Given the current implementation a machine-local DoS would be pretty trivial.)

withBinaryFileDurableAtomic and similar override permissions set by user with fchmod()

When I do

withBinaryFileDurableAtomic "myfile" WriteMode $ \handle -> do
  
  fd <- handleToFd handle
  fm <- Posix.fileMode <$> Posix.getFdStatus fd
  Posix.setFdMode fd myPermissionsHere

  return x

then myPermissionsHere results in an fchmod(), but those permissions are later overridden by an fchmod() that unliftio does just before the file is closed.

Reason

withBinaryFileDurableAtomic does

      mFileMode <- copyFileHandle iomode filePath tmpFileHandle
      res <- action tmpFileHandle
      atomicDurableTempFileRename dirFd mFileMode tmpFileHandle mTmpFilePath filePath

where mFileMode = Nothing when copyFileHandle says that the file doesn't already exist (the normal case), and atomicDurableTempFileRename runs this:

        let fileMode = fromMaybe Posix.stdFileMode mFileMode
        -- work around for the glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17523
        Posix.setFdMode fd fileMode

This means that atomicDurableTempFileRename will always call setFdMode with stdFileMode, thus erasing any permissions the user may have set in action.

Proposed solution

We should call our setFdMode before res <- action tmpFileHandle is run.


CC @lehins

Add helper function for converting exceptions?

Control.Exception has a mapException function that can convert exceptions in impure contexts, but not for exceptions thrown in a monadic context:

{-# LANGUAGE DeriveAnyClass #-}
data Exception1 = Exception1 deriving (Show, Exception)
data Exception2 = Exception2 deriving (Show, Exception)
mapException (\Exception1 -> Exception2) (throwIO Exception1)

returns Exception1. It would be great if unliftio could provide a helper that would convert exceptions in a monadic context, maybe something like

mapExceptionIO :: (MonadUnliftIO m, Exception e1, Exception e2) => (e1 -> e2) -> m a -> m a
mapExceptionIO f = handle (throwIO . f)

Test failures on Apple Silicon

building '/nix/store/c5yfj9bg2qysqvz255v14mkvsrh98k29-unliftio-0.2.19.drv'...
setupCompilerEnvironmentPhase
Build with /nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6.
unpacking sources
unpacking source archive /nix/store/a7f2grmk9qa5qdbg288abw85r4wffn02-unliftio-0.2.19.tar.gz
source root is unliftio-0.2.19
setting SOURCE_DATE_EPOCH to timestamp 1626799065 of file unliftio-0.2.19/unliftio.cabal
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/private/tmp/nix-build-unliftio-0.2.19.drv-0/setup-package.conf.d -j4 -threaded -rtsopts
[1 of 1] Compiling Main             ( Setup.hs, /private/tmp/nix-build-unliftio-0.2.19.drv-0/Main.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Linking Setup ...
updateAutotoolsGnuConfigScriptsPhase
configuring
configureFlags: --verbose --prefix=/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/bgi1j8418dcg24blq0c0aspks90prxhg-unliftio-0.2.19-doc/share/doc/unliftio-0.2.19 --with-gcc=clang --package-db=/private/tmp/nix-build-unliftio-0.2.19.drv-0/package.conf.d --ghc-options=-j4 --disable-split-objs --disable-library-profiling --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --extra-include-dirs=/nix/store/bsimh33mww300hcm1rj106ci02g0yvrd-libcxx-11.1.0-dev/include --extra-lib-dirs=/nix/store/f5nirjav817bv6wrqdqrxvy6g0ffs1vp-libcxx-11.1.0/lib --extra-include-dirs=/nix/store/303904q0nr7mv5qrdgmacd9hy5ws6c20-libcxxabi-11.1.0-dev/include --extra-lib-dirs=/nix/store/q65iy5a3jz4g10igwd0fch381cy37bb5-libcxxabi-11.1.0/lib --extra-lib-dirs=/nix/store/mz7i1ga12cb9zfpc29mq0782cfi449qf-compiler-rt-libc-11.1.0/lib --extra-lib-dirs=/nix/store/1998f6nswbff17vc97w62dvv8b131dak-ncurses-6.2/lib --extra-lib-dirs=/nix/store/mi7r8azivrjpi8m0yr84bbv6iip6702x-libffi-3.4.2/lib --extra-lib-dirs=/nix/store/zrj85hlkkfc3ifw87rvmmp15h83rayf2-gmp-6.2.1/lib --extra-include-dirs=/nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/include --extra-lib-dirs=/nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib --extra-framework-dirs=/nix/store/z54k7h2y1hcshfvgzb86lvb62s9x85nd-apple-framework-CoreFoundation-11.0.0/Library/Frameworks --extra-include-dirs=/nix/store/wxjwrich12j8zd7j33vr2zgk0c2y4mhy-libobjc-11.0.0/include --extra-lib-dirs=/nix/store/wxjwrich12j8zd7j33vr2zgk0c2y4mhy-libobjc-11.0.0/lib
Using Parsec parser
Configuring unliftio-0.2.19...
Dependency async >2.1.1: using async-2.2.3
Dependency base >=4.9 && <5: using base-4.14.3.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency deepseq -any: using deepseq-1.4.4.0
Dependency directory -any: using directory-1.3.6.0
Dependency filepath -any: using filepath-1.4.2.1
Dependency process >=1.2.0.0: using process-1.6.13.2
Dependency stm >=2.4.3: using stm-2.5.0.1
Dependency time -any: using time-1.9.3
Dependency transformers -any: using transformers-0.5.6.2
Dependency unix -any: using unix-2.7.2.2
Dependency unliftio-core >=0.1.1.0: using unliftio-core-0.2.0.1
Dependency QuickCheck -any: using QuickCheck-2.14.2
Dependency async >2.1.1: using async-2.2.3
Dependency base >=4.9 && <5: using base-4.14.3.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency containers -any: using containers-0.6.5.1
Dependency deepseq -any: using deepseq-1.4.4.0
Dependency directory -any: using directory-1.3.6.0
Dependency filepath -any: using filepath-1.4.2.1
Dependency hspec -any: using hspec-2.7.10
Dependency process >=1.2.0.0: using process-1.6.13.2
Dependency stm >=2.4.3: using stm-2.5.0.1
Dependency time -any: using time-1.9.3
Dependency transformers -any: using transformers-0.5.6.2
Dependency unix -any: using unix-2.7.2.2
Dependency unliftio -any: using unliftio-0.2.19
Dependency unliftio-core >=0.1.1.0: using unliftio-core-0.2.0.1
Source component graph:
    component lib
    component test:unliftio-spec dependency lib
Configured component graph:
    component unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        include base-4.14.3.0
        include bytestring-0.10.12.0
        include deepseq-1.4.4.0
        include directory-1.3.6.0
        include filepath-1.4.2.1
        include process-1.6.13.2
        include stm-2.5.0.1
        include time-1.9.3
        include transformers-0.5.6.2
        include unix-2.7.2.2
        include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
    component unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
        include QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
        include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        include base-4.14.3.0
        include bytestring-0.10.12.0
        include containers-0.6.5.1
        include deepseq-1.4.4.0
        include directory-1.3.6.0
        include filepath-1.4.2.1
        include hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
        include process-1.6.13.2
        include stm-2.5.0.1
        include time-1.9.3
        include transformers-0.5.6.2
        include unix-2.7.2.2
        include unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Linked component graph:
    unit unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        include base-4.14.3.0
        include bytestring-0.10.12.0
        include deepseq-1.4.4.0
        include directory-1.3.6.0
        include filepath-1.4.2.1
        include process-1.6.13.2
        include stm-2.5.0.1
        include time-1.9.3
        include transformers-0.5.6.2
        include unix-2.7.2.2
        include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
        UnliftIO=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO,UnliftIO.Async=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Async,UnliftIO.Chan=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Chan,UnliftIO.Concurrent=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Concurrent,UnliftIO.Directory=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Directory,UnliftIO.Environment=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Environment,UnliftIO.Exception=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Exception,UnliftIO.Foreign=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Foreign,UnliftIO.IO=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IO,UnliftIO.IO.File=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IO.File,UnliftIO.IORef=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IORef,UnliftIO.Internals.Async=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Internals.Async,UnliftIO.MVar=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.MVar,UnliftIO.Memoize=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Memoize,UnliftIO.Process=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Process,UnliftIO.QSem=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.QSem,UnliftIO.QSemN=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.QSemN,UnliftIO.STM=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.STM,UnliftIO.Temporary=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Temporary,UnliftIO.Timeout=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Timeout
    unit unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
        include QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
        include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        include base-4.14.3.0
        include bytestring-0.10.12.0
        include containers-0.6.5.1
        include deepseq-1.4.4.0
        include directory-1.3.6.0
        include filepath-1.4.2.1
        include hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
        include process-1.6.13.2
        include stm-2.5.0.1
        include time-1.9.3
        include transformers-0.5.6.2
        include unix-2.7.2.2
        include unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Ready component graph:
    definite unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        depends async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        depends base-4.14.3.0
        depends bytestring-0.10.12.0
        depends deepseq-1.4.4.0
        depends directory-1.3.6.0
        depends filepath-1.4.2.1
        depends process-1.6.13.2
        depends stm-2.5.0.1
        depends time-1.9.3
        depends transformers-0.5.6.2
        depends unix-2.7.2.2
        depends unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
    definite unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
        depends QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
        depends async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
        depends base-4.14.3.0
        depends bytestring-0.10.12.0
        depends containers-0.6.5.1
        depends deepseq-1.4.4.0
        depends directory-1.3.6.0
        depends filepath-1.4.2.1
        depends hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
        depends process-1.6.13.2
        depends stm-2.5.0.1
        depends time-1.9.3
        depends transformers-0.5.6.2
        depends unix-2.7.2.2
        depends unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
        depends unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Using Cabal-3.2.1.0 compiled by ghc-8.10
Using compiler: ghc-8.10.6
Using install prefix:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19
Executables installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/bin
Libraries installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/lib/ghc-8.10.6/aarch64-osx-ghc-8.10.6/unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
Dynamic Libraries installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/lib/ghc-8.10.6/aarch64-osx-ghc-8.10.6
Private executables installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/libexec/aarch64-osx-ghc-8.10.6/unliftio-0.2.19
Data files installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/share/aarch64-osx-ghc-8.10.6/unliftio-0.2.19
Documentation installed in:
/nix/store/bgi1j8418dcg24blq0c0aspks90prxhg-unliftio-0.2.19-doc/share/doc/unliftio-0.2.19
Configuration files installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/etc
No alex found
Using ar found on system at:
/nix/store/fn10hhcprz2sjfx0ps5657k24kb7inj8-cctools-binutils-darwin-949.0.1/bin/ar
No c2hs found
No cpphs found
No doctest found
Using gcc version 11.1.0 given by user at:
/nix/store/id1jfmdc8h3xrxvbz8rhsab7jpwd4y45-clang-wrapper-11.1.0/bin/clang
Using ghc version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/ghc
Using ghc-pkg version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/ghc-pkg
No ghcjs found
No ghcjs-pkg found
No greencard found
Using haddock version 2.24.2 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/haddock
No happy found
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.68 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/hpc
Using hsc2hs version 0.68.7 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/hsc2hs
Using hscolour version 1.24 found on system at:
/nix/store/ab3k6kf3j5sbmwjgvkgiaj29sxz7nsrx-hscolour-1.24.4/bin/HsColour
No jhc found
Using ld found on system at:
/nix/store/4jbmi4qkwa0g0316ri73iw8ksc4pl150-cctools-binutils-darwin-wrapper-949.0.1/bin/ld
No pkg-config found
Using runghc version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/runghc
Using strip found on system at:
/nix/store/id1jfmdc8h3xrxvbz8rhsab7jpwd4y45-clang-wrapper-11.1.0/bin/strip
Using tar found on system at:
/nix/store/2rkvd2ddbs89xhfhjcac7yi9mjf9ra2p-gnutar-1.34/bin/tar
No uhc found
building
Preprocessing library for unliftio-0.2.19..
Building library for unliftio-0.2.19..
[ 1 of 22] Compiling Paths_unliftio   ( dist/build/autogen/Paths_unliftio.hs, dist/build/Paths_unliftio.o, dist/build/Paths_unliftio.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 2 of 22] Compiling UnliftIO.Chan    ( src/UnliftIO/Chan.hs, dist/build/UnliftIO/Chan.o, dist/build/UnliftIO/Chan.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 3 of 22] Compiling UnliftIO.Directory ( src/UnliftIO/Directory.hs, dist/build/UnliftIO/Directory.o, dist/build/UnliftIO/Directory.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 4 of 22] Compiling UnliftIO.Environment ( src/UnliftIO/Environment.hs, dist/build/UnliftIO/Environment.o, dist/build/UnliftIO/Environment.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 5 of 22] Compiling UnliftIO.Exception ( src/UnliftIO/Exception.hs, dist/build/UnliftIO/Exception.o, dist/build/UnliftIO/Exception.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 6 of 22] Compiling UnliftIO.Foreign ( src/UnliftIO/Foreign.hs, dist/build/UnliftIO/Foreign.o, dist/build/UnliftIO/Foreign.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 7 of 22] Compiling UnliftIO.IO      ( src/UnliftIO/IO.hs, dist/build/UnliftIO/IO.o, dist/build/UnliftIO/IO.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
[ 8 of 22] Compiling UnliftIO.IORef   ( src/UnliftIO/IORef.hs, dist/build/UnliftIO/IORef.o, dist/build/UnliftIO/IORef.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 9 of 22] Compiling UnliftIO.Internals.Async ( src/UnliftIO/Internals/Async.hs, dist/build/UnliftIO/Internals/Async.o, dist/build/UnliftIO/Internals/Async.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[10 of 22] Compiling UnliftIO.Async   ( src/UnliftIO/Async.hs, dist/build/UnliftIO/Async.o, dist/build/UnliftIO/Async.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[11 of 22] Compiling UnliftIO.MVar    ( src/UnliftIO/MVar.hs, dist/build/UnliftIO/MVar.o, dist/build/UnliftIO/MVar.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[12 of 22] Compiling UnliftIO.IO.File.Posix ( src/UnliftIO/IO/File/Posix.hs, dist/build/UnliftIO/IO/File/Posix.o, dist/build/UnliftIO/IO/File/Posix.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
[13 of 22] Compiling UnliftIO.IO.File ( src/UnliftIO/IO/File.hs, dist/build/UnliftIO/IO/File.o, dist/build/UnliftIO/IO/File.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[14 of 22] Compiling UnliftIO.Concurrent ( src/UnliftIO/Concurrent.hs, dist/build/UnliftIO/Concurrent.o, dist/build/UnliftIO/Concurrent.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[15 of 22] Compiling UnliftIO.Memoize ( src/UnliftIO/Memoize.hs, dist/build/UnliftIO/Memoize.o, dist/build/UnliftIO/Memoize.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[16 of 22] Compiling UnliftIO.Process ( src/UnliftIO/Process.hs, dist/build/UnliftIO/Process.o, dist/build/UnliftIO/Process.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[17 of 22] Compiling UnliftIO.QSem    ( src/UnliftIO/QSem.hs, dist/build/UnliftIO/QSem.o, dist/build/UnliftIO/QSem.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[18 of 22] Compiling UnliftIO.QSemN   ( src/UnliftIO/QSemN.hs, dist/build/UnliftIO/QSemN.o, dist/build/UnliftIO/QSemN.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[19 of 22] Compiling UnliftIO.STM     ( src/UnliftIO/STM.hs, dist/build/UnliftIO/STM.o, dist/build/UnliftIO/STM.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[20 of 22] Compiling UnliftIO.Temporary ( src/UnliftIO/Temporary.hs, dist/build/UnliftIO/Temporary.o, dist/build/UnliftIO/Temporary.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[21 of 22] Compiling UnliftIO.Timeout ( src/UnliftIO/Timeout.hs, dist/build/UnliftIO/Timeout.o, dist/build/UnliftIO/Timeout.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[22 of 22] Compiling UnliftIO         ( src/UnliftIO.hs, dist/build/UnliftIO.o, dist/build/UnliftIO.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Preprocessing test suite 'unliftio-spec' for unliftio-0.2.19..
Building test suite 'unliftio-spec' for unliftio-0.2.19..
[1 of 9] Compiling Paths_unliftio   ( dist/build/unliftio-spec/autogen/Paths_unliftio.hs, dist/build/unliftio-spec/unliftio-spec-tmp/Paths_unliftio.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[2 of 9] Compiling UnliftIO.AsyncSpec ( test/UnliftIO/AsyncSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/AsyncSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[3 of 9] Compiling UnliftIO.DirectorySpec ( test/UnliftIO/DirectorySpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/DirectorySpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[4 of 9] Compiling UnliftIO.ExceptionSpec ( test/UnliftIO/ExceptionSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/ExceptionSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[5 of 9] Compiling UnliftIO.IO.FileSpec ( test/UnliftIO/IO/FileSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/IO/FileSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[6 of 9] Compiling UnliftIO.IOSpec  ( test/UnliftIO/IOSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/IOSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[7 of 9] Compiling UnliftIO.MemoizeSpec ( test/UnliftIO/MemoizeSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/MemoizeSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[8 of 9] Compiling UnliftIO.PooledAsyncSpec ( test/UnliftIO/PooledAsyncSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/PooledAsyncSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[9 of 9] Compiling Main             ( test/Spec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/Main.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Linking dist/build/unliftio-spec/unliftio-spec ...
running tests
Running 1 test suites...
Test suite unliftio-spec: RUNNING...

UnliftIO.Async
  replicateConcurrently_
    works
      +++ OK, passed 100 tests.
    uses a different thread per replicated action
      +++ OK, passed 100 tests.
  flatten
    flattens all alternative trees
  conc
    handles sync exceptions
    handles async exceptions
    has an Unmasked masking state for given subroutines
    allows to kill parent via timeout
    throws right exception on empty
  Conc Applicative instance
    doesn't fork a new thread on a pure call
      +++ OK, passed 100 tests.
    evaluates all needed sub-routines
    cleanup on brackets work
    re-throws exception that happened first
  Conc Alternative instance
    is left associative
    executes body of all alternative blocks
    finishes all threads that didn't finish first
    nesting works
UnliftIO.Directory
  createFileLink
    mirror
UnliftIO.Exception
  catchSyncOrAsync
    should catch sync exceptions
    should catch async exceptions
    should catch unliftio-wrapped async exceptions
  handleSyncOrAsync
    should catch sync exceptions
    should catch async exceptions
    should catch unliftio-wrapped async exceptions
  trySyncOrAsync
    should catch sync exceptions
    should catch async exceptions
    should catch unliftio-wrapped async exceptions
  fromExceptionUnwrap
    should be the inverse of toAsyncException
    should be the inverse of toSyncException
  pureTry
    Right for defined values
    Left for bottom
    Right for wrapped bottom
  pureTryDeep
    Right for defined values
    Left for bottom
    Left for wrapped bottom
  mapExceptionM
    should convert an exception
    should not convert unrelated exceptions
UnliftIO.IO.File
  ensureFileDurable
    ensures a file is durable with an fsync
  withBinaryFile
    read
    write
    read/write
    append
    sub-directory
    relative-directory
    modified-permissions
    exception - Does not corrupt files
      +++ OK, failed as expected. (after 1 test):
      expected: "Hello World"
       but got: "Goodbye yall"
    exception - Does not leave files behind
      +++ OK, failed as expected. (after 1 test):
      expected: False
       but got: True
    delete - file
      +++ OK, failed as expected. (after 1 test):
      expected: True
       but got: False
  writeBinaryFile
    write
    default-permissions
  withBinaryFileAtomic
    read
    write
    read/write
    append
    sub-directory
    relative-directory
    modified-permissions
    exception - Does not corrupt files
      +++ OK, passed 1 test.
    exception - Does not leave files behind
      +++ OK, passed 1 test.
    delete - file
      +++ OK, passed 1 test.
  writeBinaryFileAtomic
    write
    default-permissions
  withBinaryFileDurable
    read
    write
    read/write
    append
    sub-directory
    relative-directory
    modified-permissions
    exception - Does not corrupt files
      +++ OK, failed as expected. (after 1 test):
      expected: "Hello World"
       but got: "Goodbye yall"
    exception - Does not leave files behind
      +++ OK, failed as expected. (after 1 test):
      expected: False
       but got: True
    delete - file
      +++ OK, failed as expected. (after 1 test):
      expected: True
       but got: False
  writeBinaryFileDurable
    write FAILED [1]
    default-permissions FAILED [2]
  withBinaryFileDurableAtomic
    read
    write
    read/write
    append
    sub-directory
    relative-directory
    modified-permissions
    exception - Does not corrupt files
      +++ OK, passed 1 test.
    exception - Does not leave files behind
      +++ OK, passed 1 test.
    delete - file
      +++ OK, passed 1 test.
  writeBinaryFileDurableAtomic
    write
    default-permissions
UnliftIO.IO
  getMonotonicTime
    increases FAILED [3]
UnliftIO.Memoize
  memoizeRef
    sanity
      +++ OK, passed 100 tests.
    runs once
      +++ OK, passed 100 tests.
    runs once with exception
  memoizeMVar
    sanity
      +++ OK, passed 100 tests.
    runs once
      +++ OK, passed 100 tests.
    runs once with exception
    runs once in multiple threads
      +++ OK, passed 100 tests.
UnliftIO.PooledAsync
  pooled mapConcurrencyN
    Throws exception properly
    total thread should be >= 1
    should not spawn more than five threads for five concurrent tasks
    should not spawn more than three threads for five concurrent tasks
    should spawn only one thread
    never uses more than the given number of pools and doesn't miss any return values
      +++ OK, passed 100 tests.
  pooled mapConcurrencyN_
    Throws exception properly
    total thread should be >= 1
    find proper maximum value
    find proper maximum value with 2 threads
    find proper maximum value with 1 threads
    make sure activity is happening in different threads
    Not more than 5 threads will be spawned even if pooling is set to 8
  replicate concurrencyN
    Throws exception properly
    total thread should be >= 1
    Read tvar value should be 100
    should not spawn more than five threads for five concurrent tasks
    should not spawn more than three threads for five concurrent tasks
    should spawn only one thread
    should give empty list
    should give empty list for -ve count
  pooled replicateConcurrencyN_
    Throws exception properly
    total thread should be >= 1
    find proper maximum value
    Should be initial value

Failures:

  test/UnliftIO/IO/FileSpec.hs:165:5:
  1) UnliftIO.IO.File.writeBinaryFileDurable write
       uncaught exception: IOException of type PermissionDenied
       /private/tmp/nix-build-unliftio-0.2.19.drv-0/rio43881/writeBinaryFileDurable-write: openBinaryFile: permission denied (Permission denied)

  To rerun use: --match "/UnliftIO.IO.File/writeBinaryFileDurable/write/"

  test/UnliftIO/IO/FileSpec.hs:176:9:
  2) UnliftIO.IO.File.writeBinaryFileDurable default-permissions
       expected: Permissions {readable = True, writable = True, executable = False, searchable = False}
        but got: Permissions {readable = True, writable = False, executable = False, searchable = False}

  To rerun use: --match "/UnliftIO.IO.File/writeBinaryFileDurable/default-permissions/"

  test/UnliftIO/IOSpec.hs:14:7:
  3) UnliftIO.IO.getMonotonicTime increases
       predicate failed on: 0.0

  To rerun use: --match "/UnliftIO.IO/getMonotonicTime/increases/"

Randomized with seed 1698954143

Finished in 7.8185 seconds
118 examples, 3 failures
Test suite unliftio-spec: FAIL
Test suite logged to: dist/test/unliftio-0.2.19-unliftio-spec.log
0 of 1 test suites (0 of 1 test cases) passed.
builder for '/nix/store/c5yfj9bg2qysqvz255v14mkvsrh98k29-unliftio-0.2.19.drv' failed with exit code 1
``

Properly polymorphic `withRunInIO`.

Why not make withRunInIO properly polymorphic? There is no impredicativity involved:

withRunInIO :: MonadUnliftIO m => ((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO inner = withUnliftIO $ \u -> inner (unliftIO u)

Then

race :: MonadUnliftIO m => m a -> m b -> m (Either a b)
race a b = withRunInIO $ \runInIO -> A.race (runInIO a) (runInIO b)

`Monoid (Conc m a)` has noncanonical mappend instance

When compiling with ghc-9.2.3:

unliftio          > /.../UnliftIO/Internals/Async.hs:513:3: warning: [-Wnoncanonical-monoid-instances]
unliftio          >     Noncanonical ‘mappend’ definition detected
unliftio          >     in the instance declaration for ‘Monoid (Conc m a)’.
unliftio          >     ‘mappend’ will eventually be removed in favour of ‘(<>)’
unliftio          >     Either remove definition for ‘mappend’ (recommended) or define as ‘mappend = (<>)’
unliftio          >     See also: https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/semigroup-monoid
unliftio          >     |
unliftio          > 513 |   mappend = liftA2 mappend

instance (Monoid a, MonadUnliftIO m) => Monoid (Conc m a) where
mempty = pure mempty
{-# INLINE mempty #-}
mappend = liftA2 mappend
{-# INLINE mappend #-}

Is it possible to define a pass-through instance if the transformer constructor is not in scope?

I've been trying to define a MonadUnliftIO instance for haskeline's InputT, i.e. something like

instance MonadUnliftIO m => MonadUnliftIO (InputT m) where,

or rather for a newtype wrapper around it. Of course, I wouldn't be asking if I had succeeded.
Should I expect this to be possible if I do not have access to the internals of InputT ?

In this special case, there might be work-arounds via either the low-level IO module, or via haskeline's MonadException stuff, but of course this doesn't generalize.

catchSyncOrAsync does not catch asynchronous exceptions

#80 introduced catchSyncOrAsync and handleSyncOrAsync. It works well if a handler tries to catch SomeExeption. However, if the type of an asynchronous exception is specified, it does not catch it. This is probably because they do not take care of the async wrapper.

import Control.Concurrent hiding (throwTo)
import UnliftIO.Exception
import UnliftIO.Async

data Kill = Kill deriving (Show)

instance Exception Kill

main :: IO ()
main = do
    mvar <- newEmptyMVar
    concurrently_ (foo mvar) (bar mvar)

foo :: MVar ThreadId -> IO ()
foo mvar = handleSyncOrAsync handler $ do
    tid <- myThreadId
    putMVar mvar tid
    threadDelay 5000000
  where
    handler Kill = putStrLn "foo Killed"
--    handler (SomeException e) = putStrLn $ "foo " ++ show e

bar :: MVar ThreadId -> IO ()
bar mvar = do
    tid <- takeMVar mvar
    throwTo tid Kill

MonadUnliftIO and streaming

I've converted some of my code over to using MonadUnliftIO, but I still have a lot of code that uses the Streaming package.

[https://hackage.haskell.org/package/streaming-0.1.4.5/docs/Streaming-Internal.html]

Here's the ADT for it:

data Stream f m r = Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r

This uses MonadBase, MonadResource, MonadCatch etc, but is there any way to get this to work to support MonadUnliftIO instead?

Thanks for any help!
Grant

UnliftIO.IO.File: Expose `withHandleFd`, warn against `handleToFd`

We should expose our withHandleFd function somewhere because when you want to do something like fchmod() (which needs an Fd) on the Handle, the most luring solution is System.Posix.IO's handleToFd, which is brutally wrong because

This function has the side effect of closing the Handle

If you use handleToFd (which I just did on my server, oops), it will just mark the Handle as closed (but keep the underlying Fd open), so then the hClose that unliftio does will be silently ignored, and the Fd will be leaked until the server crashes (and so did mine).

So I think we should make our better withHandleFd publicly available, and write somewhere in the module that this is what should be used if you need low-level FD access from withBinaryFile*.


cc @lehins

HLint is triggered

I ran hlint over unliftio and unliftio-core and found:

Warnings currently triggered by your code

- [ ] Avoid lambda, 2 hints
- [ ] Avoid lambda using `infix`, 3 hints
- [ ] Eta reduce, 1 hint
- [ ] Move brackets to avoid $, 14 hints
- [ ] Redundant bracket, 34 hints
- [ ] Replace case with maybe, 1 hint
- [ ] Unused LANGUAGE pragma, 12 hints
- [ ] Use <$>, 2 hints
- [ ] Use asum, 4 hints
- [ ] Use camelCase, 19 hints
- [ ] Use const, 4 hints
- [ ] Use even, 3 hints
- [ ] Use fewer imports, 1 hint
- [ ] Use fmap, 13 hints
- [ ] Use lambda-case, 1 hint
- [ ] Use newTVarIO, 3 hints
- [ ] Use readTVarIO, 8 hints
- [ ] Use void, 1 hint
- [ ] Use when, 2 hints

Which of these do we care about?

Why no QSem and QSemN?

Hi, I use rio (and thus unliftio) a lot, and would like to get unlifted versions of Control.Concurrent.QSem and Control.Concurrent.QSemN from RIO. I know that sometimes rio does not re-export a module or a function because it has problems (like Control.Exception), and I would like to know such reasons. Is there any problem with QSem modules?

I often find scenarios where I need to easily limit concurrent jobs. For example, I spawn a child process for each request, and wait for it to finish before sending back the response. I would like to limit the number of processes running in order to avoid OOMs. I think QSem is best suited for this kind of logics. I know I can use Chan, but it requires spawning threads as workers and it's difficult to send back the response. I can also use Pool, but it seems unnecessary because the child processes are not reusable resources -- they always get destroyed after finish.

Eq instance for StringException?

Would it make sense to add an Eq instance for StringException? I'm writing tests for functions that should handle arbitrary errors, and it would be nice to just do

let e = stringException "asdf"
res <- tryAny $ withFoo (\_ -> throwIO e)
res `shouldBe` Left e

Right now, I'm forced to write my own exception type and use that.

Lifted System.IO.Temp

I've noticed that unliftio's UnliftIO.Temporary doesn't lift temporary's System.IO.Temp, but instead reimplements most of that module.

As far as I understand, the main difference between both is that temporary will create the file/temporary template based on a random string, while unliftio will use the process's PID. This may actually have surprising behavior with concurrent programs (e.g., see this issue: UnkindPartition/temporary#8), where race conditions can happen. temporary mitigates this problem.

Is there any reason unliftio reimplements the module? Wouldn't it make it easier to keep up with updates in that library?

One more thing: why not re-export getCanonicalTemporaryDirectory?

Move `askUnliftIO` out of class

When defining monad transformers as newtypes over IdentityT or ReaderT r, I'd like to simply derive an instance for UnliftIO with the newtype strategy,

newtype Newtype m a = Newtype (m a) 
  deriving newtype (Functor, Applicative, Monad, MonadIO, MonadUnliftIO)

However, this currently fails with the error

    • Couldn't match representation of type ‘m (UnliftIO (Newtype m))’
                               with that of ‘m (UnliftIO m)’
        arising from the coercion of the method ‘askUnliftIO’
          from type ‘m (UnliftIO m)’
            to type ‘Newtype m (UnliftIO (Newtype m))’
      NB: We cannot know what roles the parameters to ‘m’ have;
        we must assume that the role is nominal
    • When deriving the instance for (MonadUnliftIO (Newtype m))

This could be avoided by moving the askUnliftIO method out of the class definition. This is pretty much the breaking part of #13.

Doesn't build with monad-logger 0.3.26

[ 7 of 13] Compiling UnliftIO.Instances ( src/UnliftIO/Instances.hs, dist/build/UnliftIO/Instances.dyn_o )

src/UnliftIO/Instances.hs:11:10: error:
    Duplicate instance declarations:
      instance MonadUnliftIO m => MonadUnliftIO (LoggingT m)
        -- Defined at src/UnliftIO/Instances.hs:11:10
      instance MonadUnliftIO m => MonadUnliftIO (LoggingT m)
        -- Defined in ‘Control.Monad.Logger’
   |
11 | instance MonadUnliftIO m => MonadUnliftIO (LoggingT m) where
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/UnliftIO/Instances.hs:17:10: error:
    Duplicate instance declarations:
      instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m)
        -- Defined at src/UnliftIO/Instances.hs:17:10
      instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m)
        -- Defined in ‘Control.Monad.Logger’
   |
17 | instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

`Async.cancel` does not work inside of `withException`

Related: #74

This is a minimal reproduction of the issue we're seeing.

  describe "withException" $ do
    it "should work when withAsync is in the handler" $ do
      let
        action =
          error "oops"
            `onException` do
              let
                timerAction n = do
                  threadDelay 1000000
                  when (n < 10) $ do
                    timerAction (n + 1)
              withAsync (timerAction 0) $ \a -> do
                cancel a
      action
        `shouldThrow`
          errorCall "oops"

This should finish instantaneously, but it actually waits for timerAction to complete - all 10 seconds of it. cancel is therefore broken inside of a withException or onException or even a bracket call.

What's very surprising about this behavior is that catch doesn't share it. catch works exactly like you'd expect, even though a very simple implementation of withException is withException action handler = catch action (\e -> handler e >> throwIO e).

Include Companion?

I wrote an implementation of what I've called "companion threads" for Stack:

https://github.com/commercialhaskell/stack/blob/42b4ce73653174f777015b4099c8021b35136590/subs/pantry/src/Pantry/Internal/Companion.hs

It's theoretically a general-purpose concept, and would fit in well with this library: it introduces no additional dependencies, and nicely generalizes to MonadUnliftIO. However, I'm not sure if the idea is fully fleshed out yet and warrants being included here. Feedback welcome.

An instance for ExceptT

module UnliftExcept where

import Control.Monad.Except
import UnliftIO

instance (MonadUnliftIO m, Exception e) => MonadUnliftIO (ExceptT e m) where
    withRunInIO exceptToIO = ExceptT $ try $ do
        withRunInIO $ \runInIO ->
            exceptToIO (runInIO . (either throwIO pure <=< runExceptT))

This is probably Bad for reasons I haven't figured out yet, but it works.

throwSTM missing

Is throwSTM not exported from UnliftIO.STM on purpose, or was just forgotten about? If it is the former, I could supply a PR with adding it.

`catchSyncOrAsync` doesn't catch `SyncExceptionWrapper`

EDIT: the text/title of this issue are confused - I missed that the test that could see-through the wrapper was actually catching SomeException and doing fromExceptionUnwrap on it.

This test illustrates the issue:

    it "should catch unliftio-wrapped sync exceptions" $ do
      result <- (`catchSyncOrAsync` return) $ throwIO Control.Exception.ThreadKilled
      result `shouldBe` Control.Exception.ThreadKilled

This test currently fails:

Failures:

  test/UnliftIO/ExceptionSpec.hs:60:7: 
  1) UnliftIO.Exception.catchSyncOrAsync should catch unliftio-wrapped async exceptions
       expected: Just Exception1
        but got: Nothing

  To rerun use: --match "/UnliftIO.Exception/catchSyncOrAsync/should catch unliftio-wrapped async exceptions/"

We're doing throwIO ThreadKilled, which throws SomeException (SyncExceptionWrapper ThreadKilled).

Meanwhile, catchSyncOrAsync is not looking "through" the SyncExceptionWrapper:

catchSyncOrAsync :: (MonadUnliftIO m, Exception e) => m a -> (e -> m a) -> m a
catchSyncOrAsync f g = withRunInIO $ \run -> run f `EUnsafe.catch` \e -> run (g e)

Windows support for the operations in UnliftIO.IO.File?

Most of the file operations in UnliftIO.IO.File have disclaimers like this:

This function behaves the same as withBinaryFile on Windows platforms.

I presume that this means that atomicity and durability are not implemented on Windows.

If so, could the same guarantees be implemented on Windows too?

`writeBinaryFile*Atomic` fails on PRoot environments running on AArch64 (ARM64)

System: Ubuntu 22.04, on a PRoot environment on AAch64.
Unliftio v. 0.2.23.0

When I do:

module Main (main) where

import UnliftIO.IO.File
import Data.ByteString

main :: IO ()
main = do
  writeBinaryFile "writeBinaryFile.txt" bs
  writeBinaryFileAtomic "writeBinaryFileAtomic.txt" bs
  writeBinaryFileDurable "writeBinaryFileDurable.txt" bs
  writeBinaryFileDurableAtomic "writeBinaryFileDurableAtomic.txt" bs
  where
    bs = pack [65 .. 75]

I get 4 files, however, the ones using the atomic variant are empty:

emilio@localhost:~/testrio$ ls -l
total 1312
-rwxr-xr-x. 1 emilio emilio 1334440 Dec 28 15:18 testrio-exe
-rw-rw-r--. 1 emilio emilio      11 Dec 28 15:20 writeBinaryFile.txt
-rw-rw-rw-. 1 emilio emilio       0 Dec 28 15:20 writeBinaryFileAtomic.txt
-rw-rw-r--. 1 emilio emilio      11 Dec 28 15:20 writeBinaryFileDurable.txt
-rw-rw-rw-. 1 emilio emilio       0 Dec 28 15:20 writeBinaryFileDurableAtomic.txt

The same problem does not happen (i.e. it works as expected) when running the code on a regular virtualized environment on the same OS and hw architecture.

Any hints as to what might be happening?

Allow unliftio-core-0.1.2.0 with base-4.14

amazonka-1.6.1 (the latest release) depends on unliftio-core (==0.1.*), the latest version of which will not build with GHC 8.10 due to the dependency on base (>=4.5 && <4.14). I've got unliftio-core to build just fine with GHC 8.10 by manually allowing base >=4.5 && <4.15. I propose making a revision on the package in Hackage to allow this so that people can use amazonka with GHC 8.10.

What do you think?

base<4.14 bound is too tight

The base<4.14 prevents unliftio from being built with GHC 8.10.1. Everything seems to work after relaxing the bound, though.

`withRunInIO` as the foundation of the library

After my recent pull request gets merged, there will be no uses of withUnliftIO in the codebase. Instead it will be

withRunInIO :: MonadUnliftIO m => ((forall a. m a -> IO a) -> IO b) -> m b

everywhere. I think, the library should be build around this function instead of askUnliftIO. Consider a type class with a very similar shape:

class MonadCatch m => MonadMask m where
  mask :: ((forall a. m a -> m a) -> m b) -> m b
  -- `uninterruptibleMask` also

It's not something like

class MonadCatch m => MonadMask m where
  askMask :: m (Mask m)

This would be less readable and more clunky.

So I think it should be

class MonadIO m => MonadUnliftIO m where
  withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b

Regarding laws for withRunInIO, how about this one:

forall m a. MonadUnliftIO m => pi (x :: m a) -> withRunInIO ($ x) ~ x

?

Having both withRunInIO and askUnliftIO in the type class along with a MINIMAL pragma is an option, but to me it looks like it complicates the library. It is more convenient to define withRunInIO than askUnliftIO, because there are no newtypes involved:

instance MonadUnliftIO m => MonadUnliftIO (ReaderT r m) where
  withRunInIO k =
    ReaderT $ \r -> withRunInIO $ \run -> k $ run . flip runReaderT r

I also like that return is not used in the definition of withRunInIO. This makes it possible to generalize MonadUnliftIO to other things, maybe some functors. Just in a case.

All in all, I think, withRunInIO is the way to go.

Why is forkWithUnmask not called forkIOWithUnmask?

UnliftIO.Concurrent provides a function called forkWithUnmask, which is an unlifted variant of forkIOWithUnmask. Now, all other unlifted functions provided by the library match the name of their original -- but this does one does not. Was that choice intentional?

Unify `AsyncExceptionWrapper` and friends between `safe-exceptions` and `unliftio`

The UnliftIO.Exception module contains a large copy/paste of code and types from safe-exceptions, including items like AsyncExceptionWrapper, SyncExceptionWrapper, etc.

Program behavior may change if you switch from Control.Exception.Safe.throwTo to UnliftIO.Exception.throwTo - if you do a catch and expect an Control.Exception.Safe.AsyncExceptionWrapper, then you'll fail to catch the wrapped type.

Since the types are the same, it seems to make sense to unify them.

This could mean depending on safe-exceptions directly, or factoring the type out into a separate package.

If we do depend on safe-exceptions directly, then we can also unify Handler #101, since exceptions is a dependency of safe-exceptions.

Text mode file operations

UnliftIO.IO.File currently offers only binary mode file operations.

It would be nice if text mode operations were offered too, to simplify writing text files in a cross-platform way: On Windows, text mode writes change LF line endings to CRLF. See openBinaryFile:

On Windows, reading a file in text mode (which is the default) will translate CRLF to LF, and writing will translate LF to CRLF. This is usually what you want with text files. With binary files this is undesirable; also, as usual under Microsoft operating systems, text mode treats control-Z as EOF. Binary mode turns off all special treatment of end-of-line and end-of-file characters. (See also hSetBinaryMode.)

Add `unlift :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b`?

What do you think about adding

    unlift :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b
    unlift m x = do
      runInIO <- askRunInIO
      liftIO $ m $ runInIO x

to Control.Monad.IO.Unlift? This is handy when you have a IO a -> IO b, and avoids a little bit of boilerplate.

Usage example:

runSTControl lock stControl prepare =
  maybe (throwIO Locked) return =<< unlift (withLockTry lock) do

where withLockTry is withLockTry :: Lock -> IO a -> IO (Maybe a) from extra.

Catch sync or async exceptions

It would be great if UnliftIO.Exception could define

-- Same as catch, except only catches async, rethrowing sync
catchAsync = ...

-- Explicitly catches sync and async exceptions
catchSyncOrAsync = Unsafe.catch

along with similar functions for handle and try. I have some code that should handle async exceptions as well, but I'd like to avoid lifting my overall ban on Control.Exception, even for a single module.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.