chore: minio-runner
This commit is contained in:
parent
555d8e64e5
commit
79ec5184e6
@ -101,6 +101,7 @@ sourceFileDBChunks :: (MonadThrow m, MonadHandler m, HandlerSite m ~ UniWorX, Ba
|
|||||||
=> ((Int, Int) -> ReaderT SqlReadBackend m (Maybe ByteString) -> ReaderT SqlReadBackend m (Maybe ByteString)) -> FileContentChunkReference -> ConduitT i (ByteString, (Int, Int)) (ReaderT backend m) ()
|
=> ((Int, Int) -> ReaderT SqlReadBackend m (Maybe ByteString) -> ReaderT SqlReadBackend m (Maybe ByteString)) -> FileContentChunkReference -> ConduitT i (ByteString, (Int, Int)) (ReaderT backend m) ()
|
||||||
sourceFileDBChunks cont chunkHash = transPipe (withReaderT $ projectBackend @SqlReadBackend) $ do
|
sourceFileDBChunks cont chunkHash = transPipe (withReaderT $ projectBackend @SqlReadBackend) $ do
|
||||||
dbChunksize <- getsYesod $ view _appFileUploadDBChunksize
|
dbChunksize <- getsYesod $ view _appFileUploadDBChunksize
|
||||||
|
-- mRunner <- getMinioRunner
|
||||||
let retrieveChunk = \case
|
let retrieveChunk = \case
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just start -> do
|
Just start -> do
|
||||||
@ -109,11 +110,12 @@ sourceFileDBChunks cont chunkHash = transPipe (withReaderT $ projectBackend @Sql
|
|||||||
return $ E.substring (fileContentChunk E.^. FileContentChunkContent) (E.val start) (E.val dbChunksize)
|
return $ E.substring (fileContentChunk E.^. FileContentChunkContent) (E.val start) (E.val dbChunksize)
|
||||||
chunk <- fileChunkARC Nothing (chunkHash, (start, dbChunksize)) getChunkDB
|
chunk <- fileChunkARC Nothing (chunkHash, (start, dbChunksize)) getChunkDB
|
||||||
case chunk of
|
case chunk of
|
||||||
Nothing -> throwM SourceFilesContentUnavailable
|
|
||||||
Just c -> do
|
Just c -> do
|
||||||
return . Just . ((c, (start, dbChunksize)), ) $ if
|
return . Just . ((c, (start, dbChunksize)), ) $ if
|
||||||
| olength c >= dbChunksize -> Just $ start + dbChunksize
|
| olength c >= dbChunksize -> Just $ start + dbChunksize
|
||||||
| otherwise -> Nothing
|
| otherwise -> Nothing
|
||||||
|
-- Nothing | Just MinioRunner{..} <- mRunner -> do
|
||||||
|
Nothing -> throwM SourceFilesContentUnavailable
|
||||||
C.unfoldM retrieveChunk $ Just (1 :: Int)
|
C.unfoldM retrieveChunk $ Just (1 :: Int)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
module Handler.Utils.Minio
|
module Handler.Utils.Minio
|
||||||
( runAppMinio
|
( MinioRunner(..)
|
||||||
|
, getMinioRunner
|
||||||
|
, runAppMinio
|
||||||
, minioIsDoesNotExist
|
, minioIsDoesNotExist
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -10,14 +12,24 @@ import Network.Minio (Minio)
|
|||||||
import qualified Network.Minio as Minio
|
import qualified Network.Minio as Minio
|
||||||
|
|
||||||
|
|
||||||
|
newtype MinioRunner = MinioRunner
|
||||||
|
{ runMinio :: forall m' a. (MonadHandler m', HandlerSite m' ~ UniWorX, MonadThrow m') => Minio a -> m' a
|
||||||
|
}
|
||||||
|
|
||||||
|
getMinioRunner :: (MonadHandler m, HandlerSite m ~ UniWorX)
|
||||||
|
=> m (Maybe MinioRunner)
|
||||||
|
getMinioRunner = runMaybeT $ do
|
||||||
|
conn <- hoistMaybe =<< getsYesod appUploadCache
|
||||||
|
return MinioRunner{ runMinio = throwLeft <=< liftIO . Minio.runMinioWith conn }
|
||||||
|
|
||||||
runAppMinio :: ( MonadHandler m, HandlerSite m ~ UniWorX
|
runAppMinio :: ( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, MonadPlus m
|
, MonadPlus m
|
||||||
)
|
)
|
||||||
=> Minio a -> m a
|
=> Minio a -> m a
|
||||||
runAppMinio act = do
|
runAppMinio act = do
|
||||||
conn <- hoistMaybe =<< getsYesod appUploadCache
|
MinioRunner{..} <- hoistMaybe =<< getMinioRunner
|
||||||
throwLeft <=< liftIO $ Minio.runMinioWith conn act
|
runMinio act
|
||||||
|
|
||||||
minioIsDoesNotExist :: HttpException -> Bool
|
minioIsDoesNotExist :: HttpException -> Bool
|
||||||
minioIsDoesNotExist (HttpExceptionRequest _ (StatusCodeException resp _))
|
minioIsDoesNotExist (HttpExceptionRequest _ (StatusCodeException resp _))
|
||||||
|
|||||||
@ -6,7 +6,7 @@ module Model.Types.File
|
|||||||
, File(..), _fileTitle, _fileContent, _fileModified
|
, File(..), _fileTitle, _fileContent, _fileModified
|
||||||
, PureFile, toPureFile, fromPureFile, pureFileToFileReference, _pureFileContent
|
, PureFile, toPureFile, fromPureFile, pureFileToFileReference, _pureFileContent
|
||||||
, transFile
|
, transFile
|
||||||
, minioFileReference, etagFileReference
|
, minioFileChunkReference, minioFileReference, etagFileReference
|
||||||
, FileReference(..), _fileReferenceTitle, _fileReferenceContent, _fileReferenceModified
|
, FileReference(..), _fileReferenceTitle, _fileReferenceContent, _fileReferenceModified
|
||||||
, HasFileReference(..), IsFileReference(..), FileReferenceResidual(FileReferenceResidual, FileReferenceResidualEither, unFileReferenceResidualEither, FileReferenceResidualEntity, fileReferenceResidualEntityKey, fileReferenceResidualEntityResidual, unPureFileResidual)
|
, HasFileReference(..), IsFileReference(..), FileReferenceResidual(FileReferenceResidual, FileReferenceResidualEither, unFileReferenceResidualEither, FileReferenceResidualEntity, fileReferenceResidualEntityKey, fileReferenceResidualEntityResidual, unPureFileResidual)
|
||||||
, FileReferenceTitleMap(..)
|
, FileReferenceTitleMap(..)
|
||||||
@ -39,6 +39,8 @@ import Text.Show
|
|||||||
import qualified Data.Aeson as JSON
|
import qualified Data.Aeson as JSON
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
|
import qualified Data.Text as Text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
newtype FileContentChunkReference = FileContentChunkReference (Digest SHA3_512)
|
newtype FileContentChunkReference = FileContentChunkReference (Digest SHA3_512)
|
||||||
@ -55,6 +57,13 @@ instance PersistFieldSql FileContentChunkReference where
|
|||||||
|
|
||||||
makeWrapped ''FileContentChunkReference
|
makeWrapped ''FileContentChunkReference
|
||||||
|
|
||||||
|
minioFileChunkReference :: Prism' Minio.Object FileContentReference
|
||||||
|
minioFileChunkReference = prism' toObjectName fromObjectName
|
||||||
|
where toObjectName = (chunkPrefix <>) . decodeUtf8 . Base64.encodeUnpadded . ByteArray.convert
|
||||||
|
fromObjectName = fmap (review _Wrapped) . Crypto.digestFromByteString <=< preview _Right . Base64.decodeUnpadded . encodeUtf8 <=< Text.stripPrefix chunkPrefix
|
||||||
|
|
||||||
|
chunkPrefix = "partial."
|
||||||
|
|
||||||
newtype FileContentReference = FileContentReference (Digest SHA3_512)
|
newtype FileContentReference = FileContentReference (Digest SHA3_512)
|
||||||
deriving (Eq, Ord, Read, Show, Lift, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Lift, Generic, Typeable)
|
||||||
deriving newtype ( PersistField
|
deriving newtype ( PersistField
|
||||||
|
|||||||
15
test/Crypto/Hash/TestInstances.hs
Normal file
15
test/Crypto/Hash/TestInstances.hs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
module Crypto.Hash.TestInstances
|
||||||
|
() where
|
||||||
|
|
||||||
|
import Crypto.Hash (Digest, HashAlgorithm)
|
||||||
|
import qualified Crypto.Hash as Crypto
|
||||||
|
import TestImport
|
||||||
|
import qualified Data.ByteArray as BA
|
||||||
|
|
||||||
|
|
||||||
|
instance HashAlgorithm a => Arbitrary (Digest a) where
|
||||||
|
arbitrary = Crypto.hash @ByteString @a <$> arbitrary
|
||||||
|
instance CoArbitrary (Digest a) where
|
||||||
|
coarbitrary = coarbitrary . BA.convert @_ @ByteString
|
||||||
|
instance HashAlgorithm a => Function (Digest a) where
|
||||||
|
function = functionShow
|
||||||
@ -57,6 +57,13 @@ instance Arbitrary (FileReferenceTitleMap fileid (FileFieldUserOption Bool)) =>
|
|||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
|
deriving newtype instance Arbitrary FileContentReference
|
||||||
|
instance CoArbitrary FileContentReference
|
||||||
|
instance Function FileContentReference
|
||||||
|
deriving newtype instance Arbitrary FileContentChunkReference
|
||||||
|
instance CoArbitrary FileContentChunkReference
|
||||||
|
instance Function FileContentChunkReference
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec = do
|
||||||
parallel $ do
|
parallel $ do
|
||||||
@ -70,3 +77,10 @@ spec = do
|
|||||||
[ eqLaws, ordLaws, semigroupLaws, monoidLaws, semigroupMonoidLaws, idempotentSemigroupLaws ]
|
[ eqLaws, ordLaws, semigroupLaws, monoidLaws, semigroupMonoidLaws, idempotentSemigroupLaws ]
|
||||||
lawsCheckHspec (Proxy @(FileField FileReference))
|
lawsCheckHspec (Proxy @(FileField FileReference))
|
||||||
[ eqLaws, ordLaws, jsonLaws ]
|
[ eqLaws, ordLaws, jsonLaws ]
|
||||||
|
lawsCheckHspec (Proxy @FileContentChunkReference)
|
||||||
|
[ eqLaws, ordLaws, showLaws, persistFieldLaws, pathPieceLaws, httpApiDataLaws, jsonLaws, hashableLaws, binaryLaws ]
|
||||||
|
lawsCheckHspec (Proxy @FileContentReference)
|
||||||
|
[ eqLaws, ordLaws, showLaws, persistFieldLaws, pathPieceLaws, httpApiDataLaws, jsonLaws, hashableLaws, binaryLaws ]
|
||||||
|
|
||||||
|
describe "minioFileChunkReference" . it "is a prism" . property $ isPrism minioFileChunkReference
|
||||||
|
describe "minioFileReference" . it "is a prism" . property $ isPrism minioFileReference
|
||||||
|
|||||||
@ -5,3 +5,4 @@ module TestInstances
|
|||||||
import Text.Blaze.TestInstances as TestInstances ()
|
import Text.Blaze.TestInstances as TestInstances ()
|
||||||
import Database.Persist.Sql.Types.TestInstances as TestInstances ()
|
import Database.Persist.Sql.Types.TestInstances as TestInstances ()
|
||||||
import Data.NonNull.TestInstances as TestInstances ()
|
import Data.NonNull.TestInstances as TestInstances ()
|
||||||
|
import Crypto.Hash.TestInstances as TestInstances ()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user