packages feed

Z-IO 0.1.6.0 → 0.1.6.1

raw patch · 21 files changed

+72/−63 lines, 21 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Z.IO.Environment: ResUsage :: {-# UNPACK #-} !TimeVal -> {-# UNPACK #-} !TimeVal -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> {-# UNPACK #-} !Word64 -> ResUsage
+ Z.IO.Environment: [ru_idrss] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_inblock] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_isrss] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_ixrss] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_majflt] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_maxrss] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_minflt] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_msgrcv] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_msgsnd] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_nivcsw] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_nsignals] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_nswap] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_nvcsw] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_oublock] :: ResUsage -> {-# UNPACK #-} !Word64
+ Z.IO.Environment: [ru_stime] :: ResUsage -> {-# UNPACK #-} !TimeVal
+ Z.IO.Environment: [ru_utime] :: ResUsage -> {-# UNPACK #-} !TimeVal
+ Z.IO.Environment: data ResUsage
+ Z.IO.Logger: type Level = CBytes
+ Z.IO.LowResTimer: TimeOutException :: ThreadId -> CallStack -> TimeOutException
+ Z.IO.LowResTimer: data TimeOutException
- Z.IO.Logger: type LogFormatter = Builder () " data/time string" -> Level " log level" -> Builder () " log content" -> CallStack " call stack trace" -> Builder ()
+ Z.IO.Logger: type LogFormatter = Builder () " data\/time string" -> Level " log level" -> Builder () " log content" -> CallStack " call stack trace" -> Builder ()

Files

ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for Z-IO +## 0.1.6.1  -- 2020-10-17++* Export `ResUsage` from `Z.IO.Environment`.+* Export `Level` from `Z.IO.Logger`.+* Add linefeed with default logger formattor.+ ## 0.1.6.0  -- 2020-10-17  * Fix a bug affects udp exception raising(simliar to the one fixed in 0.1.5.2).
README.md view
@@ -1,6 +1,6 @@ ## Z-IO -[![Hackage](https://img.shields.io/hackage/v/Z-IO.svg?style=flat)](https://hackage.haskell.org/package/Z-IO) [![Linux Build Status](https://github.com/haskell-Z/z-io/workflows/ubuntu-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions) [![MacOS Build Status](https://github.com/haskell-Z/z-io/workflows/oxs-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions) [![Windows Build Status](https://github.com/haskell-Z/z-io/workflows/win-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions)+[![Hackage](https://img.shields.io/hackage/v/Z-IO.svg?style=flat)](https://hackage.haskell.org/package/Z-IO) [![Linux Build Status](https://github.com/haskell-Z/z-io/workflows/ubuntu-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions) [![MacOS Build Status](https://github.com/haskell-Z/z-io/workflows/osx-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions) [![Windows Build Status](https://github.com/haskell-Z/z-io/workflows/win-ci/badge.svg)](https://github.com/haskell-Z/z-io/actions)  This package is part of [Z](https://github.com/haskell-Z/Z) project, provides basic IO operations: 
Z-IO.cabal view
@@ -1,6 +1,6 @@ cabal-version:              2.4 name:                       Z-IO-version:                    0.1.6.0+version:                    0.1.6.1 synopsis:                   Simple and high performance IO toolkit for Haskell description:                Simple and high performance IO toolkit for Haskell, including                             file system, network, ipc and more!
Z/Compression/Zlib.hsc view
@@ -285,8 +285,11 @@ toZErrorMsg (#const Z_VERSION_ERROR) =  "Z_VERSION_ERROR" toZErrorMsg _                        =  "Z_UNEXPECTED" +-- | Zlib exceptions, a sub exception type to 'SomeIOException'. data ZlibException = ZlibException CBytes CallStack deriving (Show, Typeable)-instance Exception ZlibException+instance Exception ZlibException where+    toException = ioExceptionToException+    fromException = ioExceptionFromException  throwZlibIfMinus :: HasCallStack => IO CInt -> IO CInt throwZlibIfMinus f = do
Z/IO/Buffered.hs view
@@ -227,6 +227,7 @@ readAll' :: (HasCallStack, Input i) => BufferedInput i -> IO V.Bytes readAll' i = V.concat <$> readAll i +-- | Exceptions related to buffered IO. A sub exception type to 'SomeIOException'. data BufferedException = ParseException P.ParseError CallStack                        | ShortReadException CallStack deriving (Show, Typeable) 
Z/IO/Environment.hs view
@@ -19,7 +19,7 @@   , setEnv, unsetEnv     -- * other environment infos   , getCWD, chDir, getHomeDir, getTempDir-  , getResUsage+  , getResUsage, ResUsage(..)   , getResidentSetMemory   , getUpTime   , getHighResolutionTime
Z/IO/Exception.hs view
@@ -28,7 +28,7 @@ @  If you're dealing with OS's errno directly, you should convert the errno to libuv's errno in C side with-'uv_translate_sys_error' from @hs_uv.h@, then use 'throwUVIfMinus/throwUVError' from this module.+'uv_translate_sys_error' from @hs_uv.h@, then use 'throwUVIfMinus\/throwUVError' from this module.  -} 
Z/IO/Logger.hs view
@@ -9,15 +9,14 @@  Simple, high performance logger. The design choice of this logger is biased towards simplicity instead of generlization: -    * All log functions lives in 'IO'.-    * By default this logger is connected to stderr, use 'setDefaultLogger' to customize.-    * When logging each thread will build log 'Builder's into a small 'V.Bytes' with line buffer-      instead of leaving all 'Builder's to the flushing thread:-        * Logger won't keep heap data for too long simply because they're referenced by log's 'Builder'.-        * Each logging thread only need perform a CAS to prepend log 'V.Bytes' into a list,-          which reduces contention.-        * Each log call is atomic, Logging order is preserved under concurrent settings.+* All log functions live in 'IO'.+* By default this logger is connected to stderr, use 'setDefaultLogger' to customize.+* When logging each thread will build log 'Builder's into a small 'V.Bytes' with line buffer instead of leaving all 'Builder's to the flushing thread: +    * Logger won't keep heap data for too long simply because they're referenced by log's 'Builder'.+    * Each logging thread only need perform a CAS to prepend log 'V.Bytes' into a list, which reduces contention.+    * Each log call is atomic, Logging order is preserved under concurrent settings.+ Flushing is automatic and throttled for 'debug', 'info', 'warn' to boost performance, but a 'fatal' log will always flush logger's buffer.  This could lead to a problem that if main thread exits too early logs may missed, to add a flushing when program exits, use 'withDefaultLogger' like:  @@@ -48,6 +47,7 @@   , warn   , fatal   , otherLevel+  , Level     -- * logging functions with specific logger   , debugTo   , infoTo@@ -76,7 +76,7 @@ import qualified Z.Data.Builder as B import qualified Z.Data.CBytes as CB -type LogFormatter = B.Builder ()            -- ^ data/time string+type LogFormatter = B.Builder ()            -- ^ data\/time string                   -> Level                  -- ^ log level                   -> B.Builder ()           -- ^ log content                   -> CallStack              -- ^ call stack trace@@ -86,27 +86,23 @@     { loggerPushBuilder     :: B.Builder () -> IO () -- ^ push log into buffer     , flushLogger           :: IO ()                -- ^ flush logger's buffer to output device     , flushLoggerThrottled  :: IO ()                -- ^ throttled flush, e.g. use 'throttleTrailing_' from "Z.IO.LowResTimer"-    , loggerTSCache         :: IO (B.Builder ())    -- ^ A IO action return a formatted date/time string+    , loggerTSCache         :: IO (B.Builder ())    -- ^ A IO action return a formatted date\/time string     , loggerFmt             :: LogFormatter     }  data LoggerConfig = LoggerConfig     { loggerMinFlushInterval :: {-# UNPACK #-} !Int -- ^ Minimal flush interval, see Notes on 'debug'-    , loggerLineBufSize      :: {-# UNPACK #-} !Int -- ^ Buffer size to build each log/line+    , loggerLineBufSize      :: {-# UNPACK #-} !Int -- ^ Buffer size to build each log line     , loggerShowDebug        :: Bool                -- ^ Set to 'False' to filter debug logs     }  -- | A default logger config with -----   * debug ON---   * 0.1s minimal flush interval---   * line buffer size 128 bytes---   * show debug True---   * show timestamp True---   * don't show source location---   * buffer size equals to 'V.defaultChunkSize'.+-- * 0.1s minimal flush interval+-- * line buffer size 240 bytes+-- * show debug True defaultLoggerConfig :: LoggerConfig-defaultLoggerConfig = LoggerConfig 1 128 True+defaultLoggerConfig = LoggerConfig 1 240 True  -- | A default timestamp cache with format @%Y-%m-%dT%H:%M:%S%Z@ --@@ -170,7 +166,7 @@  -- | A default log formatter ----- @ [DEBUG][2020-10-09T07:44:14UTC][<interactive>:7:1]This a debug message@+-- @ [DEBUG][2020-10-09T07:44:14UTC][<interactive>:7:1]This a debug message\\n@ defaultFmt :: Bool  -- ^ show DEGUG?            -> LogFormatter defaultFmt showdebug ts level content cstack = when (showdebug || level /= "DEBUG") $ do@@ -178,6 +174,7 @@     B.square ts     B.square $ defaultFmtCallStack cstack     content+    B.char8 '\n'  -- | A default colored log formatter --@@ -194,6 +191,7 @@     B.square ts     B.square $ defaultFmtCallStack cstack     content+    B.char8 '\n'  -- | Default stack formatter which fetch the logging source and location. defaultFmtCallStack :: CallStack -> B.Builder ()
Z/IO/LowResTimer.hs view
@@ -9,7 +9,7 @@  This module provide low resolution (0.1s) timers using a timing wheel of size 128 per capability, each timer thread will automatically started or stopped based on demannd. register or cancel a timeout is O(1),-and each step only need scan n/128 items given timers are registered in an even fashion.+and each step only need scan n\/128 items given timers are registered in an even fashion.  This timer is particularly suitable for high concurrent approximated IO timeout scheduling. You should not rely on it to provide timing information since it's very inaccurate.@@ -35,6 +35,7 @@   , throttle   , throttle_   , throttleTrailing_+  , TimeOutException(..)     -- * low resolution timer manager   , LowResTimerManager   , getLowResTimerManager@@ -209,12 +210,10 @@               -> IO (Maybe a) timeoutLowRes timeo io = do     mid <- myThreadId-    catch-        (do timer <- registerLowResTimer timeo (timeoutAThread mid)-            r <- io-            _ <- cancelLowResTimer timer-            return (Just r))-        ( \ (_ :: TimeOutException) -> return Nothing )+    bracket+        (registerLowResTimer timeo (timeoutAThread mid))+        (void . cancelLowResTimer)+        (\ _ -> catch (Just <$> io) (\ (_ :: TimeOutException) -> return Nothing))   where     timeoutAThread tid = void . forkIO $ throwTo tid (TimeOutException tid undefined) @@ -226,15 +225,18 @@                 -> IO a timeoutLowResEx timeo io = do     mid <- myThreadId-    timer <- registerLowResTimer timeo (timeoutAThread mid)-    r <- io-    _ <- cancelLowResTimer timer-    return r+    bracket+        (registerLowResTimer timeo (timeoutAThread mid))+        (void . cancelLowResTimer)+        (\ _ -> io)   where     timeoutAThread tid = void . forkIO $ throwTo tid (TimeOutException tid callStack) +-- | Exception used to stop a haskell thread when time out, a sub exception type to 'SomeIOException'. data TimeOutException = TimeOutException ThreadId CallStack deriving Show-instance Exception TimeOutException+instance Exception TimeOutException where+    toException = ioExceptionToException+    fromException = ioExceptionFromException  -------------------------------------------------------------------------------- -- | Check if low resolution timer manager loop is running, start loop if not.
Z/IO/Network.hs view
@@ -1,6 +1,6 @@ {-| Module      : Z.IO.Network-Description : DNS, TCP, UDP, IPC+Description : Network Umbrella module, DNS, TCP, UDP, IPC Copyright   : (c) Dong Han, 2020 License     : BSD Maintainer  : winterland1989@gmail.com
Z/IO/Network/DNS.hsc view
@@ -1,6 +1,6 @@ {-| Module      : Z.IO.Network.DNS-Description : TCP/UDP socket address API+Description : DNS and reverse DNS Copyright   : (c) Winterland, 2018 License     : BSD Maintainer  : drkoster@qq.com
Z/IO/Network/IPC.hs view
@@ -1,6 +1,6 @@ {-| Module      : Z.IO.IPC-Description : Named pipe/Unix domain servers and clients+Description : Named pipe\/Unix domain servers and clients Copyright   : (c) Dong Han, 2018 License     : BSD Maintainer  : winterland1989@gmail.com@@ -55,7 +55,7 @@     , ipcTargetName :: CBytes       -- ^ target path (Unix) or a name (Windows).     } --- | Default config, connect to "./ipc".+-- | Default config, connect to ".\/ipc". -- defaultIPCClientConfig :: IPCClientConfig defaultIPCClientConfig = IPCClientConfig Nothing "./ipc"@@ -85,7 +85,7 @@     , ipcListenBacklog    :: Int           -- ^ listening pipe's backlog size, should be large enough(>128)     } --- | A default hello world server on @./ipc@+-- | A default hello world server on @.\/ipc@ -- -- Test it with @main = startIPCServer defaultIPCServerConfig@ --
Z/IO/Network/SocketAddr.hsc view
@@ -1,6 +1,6 @@ {-| Module      : Z.IO.Network.SocketAddr-Description : TCP/UDP socket address API+Description : TCP\/UDP socket address API Copyright   : (c) Winterland, 2018 License     : BSD Maintainer  : drkoster@qq.com
Z/IO/Network/TCP.hs view
@@ -204,12 +204,12 @@ initTCPStream :: HasCallStack => UVManager -> Resource UVStream initTCPStream = initUVStream (\ loop hdl -> throwUVIfMinus_ (uv_tcp_init loop hdl)) --- | Enable or disable @TCP_NODELAY@, which disables Nagle’s algorithm.+-- | Enable or disable @TCP_NODELAY@, which enable or disable Nagle’s algorithm. setTCPNoDelay :: HasCallStack => UVStream -> Bool -> IO () setTCPNoDelay uvs nodelay =     throwUVIfMinus_ (uv_tcp_nodelay (uvsHandle uvs) (if nodelay then 1 else 0)) --- Enable / disable TCP keep-alive. delay is the initial delay in seconds, ignored when enable is zero.+-- | Enable \/ disable TCP keep-alive. delay is the initial delay in seconds, ignored when enable is zero. -- -- After delay has been reached, 10 successive probes, each spaced 1 second from the previous one, -- will still happen. If the connection is still lost at the end of this procedure,
Z/IO/Network/UDP.hs view
@@ -81,7 +81,7 @@  -- | UDP socket client. ----- UDP is not a sequential protocol, thus not an instance of 'Input/Output'.+-- UDP is not a sequential protocol, thus not an instance of 'Input\/Output'. -- Message are received or sent individually, UDP socket client is NOT thread safe! -- Use 'MVar' 'UDP' in multiple threads. --@@ -384,7 +384,7 @@                 -- init uv_check_t must come after poking buffer                 throwUVIfMinus_ $ hs_uv_udp_check_start check             forever $ do-                msgs <- recvUDPWith udp check buf bufSiz+                msgs <- recvUDPWith udp buf bufSiz                 withMutablePrimArrayContents rbufArr $ \ p ->                     pokeBufferTable uvm slot (castPtr p) (bufArrSiz-1)                 forM_ msgs worker@@ -405,15 +405,14 @@                 pokeBufferTable uvm slot (castPtr p) (bufArrSiz-1)                 -- init uv_check_t must come after poking buffer                 throwUVIfMinus_ $ hs_uv_udp_check_start check-            recvUDPWith udp check buf bufSiz+            recvUDPWith udp buf bufSiz  recvUDPWith :: HasCallStack             => UDP-            -> Ptr UVHandle -- ^ uv_check_t             -> (A.MutablePrimArray RealWorld Word8, A.MutablePrimArray RealWorld (Ptr Word8))             -> Int32             -> IO [(Maybe SocketAddr, Bool, V.Bytes)]-recvUDPWith udp@(UDP hdl slot uvm _ _) check (rubf, rbufArr) bufSiz =+recvUDPWith udp@(UDP hdl slot uvm _ _) (rubf, rbufArr) bufSiz =     -- It's important to keep recv buffer alive, even if we don't directly use it     mask_ . withMutablePrimArrayContents rubf $ \ _ -> do         checkUDPClosed udp
Z/IO/Process.hsc view
@@ -85,7 +85,7 @@  #include "uv.h" --- | Default process options, start @"./main"@ with no arguments, redirect all std streams to @/dev/null@.+-- | Default process options, start @".\/main"@ with no arguments, redirect all std streams to @\/dev\/null@. defaultProcessOptions :: ProcessOptions defaultProcessOptions = ProcessOptions     { processFile = "./main"@@ -140,12 +140,12 @@ -- created during spawn. -- -- @---    initProcess defaultProcessOptions{---          processFile="your program" ---      ,   processStdStreams = (ProcessCreate, ProcessCreate, ProcessCreate)---      } $ (stdin, stdout, stderr, pstate) -> do---      ... -- read or write from child process's std stream, will clean up automatically---      waitProcessExit pstate  -- wait for process exit on current thread.+-- initProcess defaultProcessOptions{+--       processFile="your program" +--   ,   processStdStreams = (ProcessCreate, ProcessCreate, ProcessCreate)+--   } $ (stdin, stdout, stderr, pstate) -> do+--   ... -- read or write from child process's std stream, will clean up automatically+--   waitProcessExit pstate  -- wait for process exit on current thread. -- @ initProcess :: ProcessOptions -> Resource (Maybe UVStream, Maybe UVStream, Maybe UVStream, TVar ProcessState) initProcess opt = initResource (spawn opt) $ \ (s0,s1,s2, pstate) -> void . forkIO $ do
Z/IO/Time.hs view
@@ -95,10 +95,10 @@ -- The result depends on the TZ environment variable. -- -- @--- > setEnv "TZ" "Africa/Algiers"+-- > setEnv "TZ" "Africa\/Algiers" -- parseSystemTime simpleDateFormat "1970-01-01 00:00:00" -- MkSystemTime {systemSeconds = 0, systemNanoseconds = 0}--- > setEnv "TZ" "Asia/Shanghai"+-- > setEnv "TZ" "Asia\/Shanghai" -- parseSystemTime simpleDateFormat "1970-01-01 00:00:00" -- MkSystemTime {systemSeconds = -28800, systemNanoseconds = 0} -- @
Z/IO/UV/Errno.hsc view
@@ -20,11 +20,13 @@  #include "hs_uv.h" +-- | Returns the error message for the given error code. Leaks a few bytes of memory when you call it with an unknown error code. uvStdError :: CInt -> IO Text uvStdError errno = toText <$> (fromCString =<< uv_strerror errno)  foreign import ccall unsafe uv_strerror :: CInt -> IO CString +-- | Returns the error name for the given error code. Leaks a few bytes of memory when you call it with an unknown error code. uvErrName :: CInt -> IO Text uvErrName errno = toText <$> (fromCString =<< uv_err_name errno) 
Z/IO/UV/FFI.hsc view
@@ -778,7 +778,7 @@         deriving anyclass (ShowT, EncodeJSON, ToValue, FromValue)  data ProcessStdStream-    = ProcessIgnore     -- ^ redirect process std stream to /dev/null+    = ProcessIgnore     -- ^ redirect process std stream to \/dev\/null     | ProcessCreate     -- ^ create a new std stream     | ProcessInherit FD -- ^ pass an existing FD to child process as std stream   deriving  (Eq, Ord, Show, Generic)
Z/IO/UV/Manager.hs view
@@ -57,8 +57,6 @@ import           Z.IO.Resource import           Z.IO.UV.FFI -#define IDLE_LIMIT 20- --------------------------------------------------------------------------------  data UVManager = UVManager
test/Z/IO/ResourceSpec.hs view
@@ -34,7 +34,7 @@              threadDelay 5000000 -- first 100 worker quickly get resources                                 -- then hold for 1s, rest 100 worker have to wait, and so on-                                -- so here we wait for 2s to make sure every worker got a resource+                                -- so here we wait for 5s to make sure every worker got a resource                                 -- we used to use replicateConcurrently_ from async, but it's                                 -- not really neccessary