graphql-engine/server/src-lib/Data/TByteString.hs
Vamshi Surabhi c52bfc540d
More robust forking, exception safety. Closes #3768 (#3860)
This is the result of a general audit of how we fork threads, with a
detour into how we're using mutable state especially in websocket
codepaths, making more robust to async exceptions and exceptions
resulting from bugs.

Some highlights:
- use a wrapper around 'immortal' so threads that die due to bugs are
  restarted, and log the error
- use 'withAsync' some places
- use bracket a few places where we might break invariants
- log some codepaths that represent bugs
- export UnstructuredLog for ad hoc logging (the alternative is we
  continue not logging useful stuff)

I had to timebox this. There are a few TODOs I didn't want to address.
And we'll wait until this is merged to attempt #3705 for
Control.Concurrent.Extended
2020-03-05 23:29:26 +05:30

45 lines
1.2 KiB
Haskell

module Data.TByteString
( TByteString
, fromText
, fromBS
, fromLBS
) where
import qualified Data.Aeson as J
import qualified Data.ByteString as B
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Data.Bool (bool)
import Data.String
import Prelude
-- | A JSON-serializable type for either text or raw binary data, encoded with base-64.
newtype TByteString
= TByteString (Bool, T.Text)
deriving (Show, Eq)
instance J.ToJSON TByteString where
toJSON (TByteString (isBase64, t)) =
bool (J.toJSON t) (J.toJSON ["Base64", t]) isBase64
instance IsString TByteString where
fromString = fromText . T.pack
fromText :: T.Text -> TByteString
fromText t = TByteString (False, t)
fromBS :: B.ByteString -> TByteString
fromBS bs =
TByteString $
-- if the bs in not utf-8 encoded, encode it to Base64
case TE.decodeUtf8' bs of
Left _ -> (True, TE.decodeUtf8 $ B64.encode bs)
Right t -> (False, t)
fromLBS :: BL.ByteString -> TByteString
fromLBS =
fromBS . BL.toStrict