Establish host properties and isolated kind matrix
This commit is contained in:
parent
84ccfdb445
commit
06d1383456
2 changed files with 1076 additions and 120 deletions
|
|
@ -14,17 +14,21 @@ import Data.Char (isControl)
|
|||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as TE
|
||||
import qualified Data.Text.Normalize as TN
|
||||
import Nuthatch.Types
|
||||
|
||||
validateRelativePath :: Text -> Either Text RelativePath
|
||||
validateRelativePath raw = do
|
||||
let path = T.dropWhile (== '/') raw
|
||||
if T.null path
|
||||
if T.null raw
|
||||
then Left "path must not be empty"
|
||||
else if T.head raw == '/' || T.last raw == '/'
|
||||
then Left "path must not begin or end with a separator"
|
||||
else if TN.normalize TN.NFC raw /= raw
|
||||
then Left "path must be NFC-normalized"
|
||||
else do
|
||||
let segments = T.splitOn "/" path
|
||||
let segments = T.splitOn "/" raw
|
||||
mapM_ validateSegment segments
|
||||
pure (RelativePath path)
|
||||
pure (RelativePath raw)
|
||||
where
|
||||
validateSegment seg
|
||||
| T.null seg = Left "empty path segment"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ module Nuthatch.Protocol
|
|||
, claimActiveBatch
|
||||
, lookupMutation
|
||||
, lookupObjectMeta
|
||||
, sameFingerprint
|
||||
, growthBytes
|
||||
, quotaAllows
|
||||
, terminalExpiryEligible
|
||||
, recoveryEligible
|
||||
, desiredMatches
|
||||
, priorMatches
|
||||
) where
|
||||
|
|
@ -105,6 +110,21 @@ sameFingerprint rec kind key size msha =
|
|||
&& mrDeclaredSize rec == size
|
||||
&& mrContentSha256 rec == msha
|
||||
|
||||
growthBytes :: Integer -> Integer -> Integer
|
||||
growthBytes priorSize desiredSize = max 0 (desiredSize - priorSize)
|
||||
|
||||
quotaAllows :: Integer -> Integer -> Integer -> Integer -> Bool
|
||||
quotaAllows limitBytes usedBytes reservedBytes growth =
|
||||
usedBytes + reservedBytes + growth <= limitBytes
|
||||
|
||||
terminalExpiryEligible :: MutationState -> ExternalState -> Bool
|
||||
terminalExpiryEligible state external =
|
||||
state `elem` [Succeeded, Failed, Rejected] && external == ExtIdle
|
||||
|
||||
recoveryEligible :: MutationState -> Integer -> Integer -> Bool
|
||||
recoveryEligible state elapsedSeconds graceSeconds =
|
||||
state `elem` [Prepared, Applying] && elapsedSeconds > graceSeconds
|
||||
|
||||
admitMutation
|
||||
:: Connection
|
||||
-> UserId
|
||||
|
|
@ -131,7 +151,7 @@ admitMutation conn uid kind op pool key rel size msha maxObject = do
|
|||
desiredSize = case kind of
|
||||
Put -> size
|
||||
Delete -> 0
|
||||
growth = max 0 (desiredSize - priorSize)
|
||||
growth = growthBytes priorSize desiredSize
|
||||
baseRec state =
|
||||
MutationRecord
|
||||
{ mrUserId = uid
|
||||
|
|
@ -416,13 +436,12 @@ desiredMatches rec = \case
|
|||
Put -> False
|
||||
ObjectPresent sz msha ->
|
||||
case mrKind rec of
|
||||
Delete -> sz == 0
|
||||
Delete -> False
|
||||
Put ->
|
||||
sz == mrDeclaredSize rec
|
||||
&& case (mrContentSha256 rec, msha) of
|
||||
(Just want, Just got) -> want == got
|
||||
-- Some stores omit custom metadata on HEAD.
|
||||
(Just _, Nothing) -> True
|
||||
(Just _, Nothing) -> False
|
||||
(Nothing, _) -> True
|
||||
|
||||
priorMatches :: MutationRecord -> ObjectObservation -> Bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue