@@ -24,9 +24,15 @@ module Cardano.Benchmarking.PullFiction.Config.Raw
2424 -- * Config.
2525 Config (.. )
2626
27+ -- * Observer.
28+ , Observer (.. )
29+
2730 -- * Builder.
2831 , Builder (.. )
2932
33+ -- * Recycle strategy.
34+ , RecycleStrategy (.. )
35+
3036 -- * RateLimit.
3137 , RateLimit (.. )
3238 -- ** TopLevelScope.
@@ -74,6 +80,10 @@ data Config = Config
7480 { -- | Raw JSON value describing how to load initial inputs.
7581 -- Interpretation is left to the caller (e.g. @Main.hs@).
7682 initialInputs :: ! Aeson. Value
83+ -- | Optional @\"observers\"@ map (keyed by name).
84+ -- Because Aeson decodes JSON objects into a 'Map', duplicate observer names
85+ -- are silently discarded (last value wins).
86+ , maybeObservers :: ! (Maybe (Map String Observer ))
7787 -- | Optional top level @\"builder\"@.
7888 , maybeTopLevelBuilder :: ! (Maybe Builder )
7989 -- | Optional top-level @\"rate_limit\"@.
@@ -82,22 +92,45 @@ data Config = Config
8292 , maybeTopLevelMaxBatchSize :: ! (Maybe Natural )
8393 -- | Optional top-level @\"on_exhaustion\"@.
8494 , maybeTopLevelOnExhaustion :: ! (Maybe OnExhaustion )
85- -- | Generator workloads keyed by name. Because Aeson decodes JSON objects
86- -- into a 'Map', duplicate workload names are silently discarded (last
87- -- value wins).
88- , workloads :: ! (Map String Workload )
95+ -- | Optional generator workloads keyed by name.
96+ -- Because Aeson decodes JSON objects into a 'Map', duplicate workload names
97+ -- are silently discarded (last value wins).
98+ , maybeWorkloads :: ! (Maybe ( Map String Workload ) )
8999 }
90100 deriving (Show , Eq )
91101
92102instance Aeson. FromJSON Config where
93103 parseJSON = Aeson. withObject " Config" $ \ o ->
94104 Config
95105 <$> o .: " initial_inputs"
106+ <*> o .:? " observers"
96107 <*> o .:? " builder"
97- <*> Aeson.Types. explicitParseFieldMaybe parseTopLevelRateLimit o " rate_limit"
108+ <*> Aeson.Types. explicitParseFieldMaybe parseTopLevelRateLimit o
109+ " rate_limit"
98110 <*> o .:? " max_batch_size"
99111 <*> o .:? " on_exhaustion"
100- <*> o .: " workloads"
112+ <*> o .:? " workloads"
113+
114+ --------------------------------------------------------------------------------
115+
116+ -- | Opaque observer configuration.
117+ --
118+ -- Carries a @\"type\"@ discriminator and an opaque @\"params\"@ object.
119+ -- Interpretation of the params is the caller's responsibility (see @Main.hs@),
120+ -- just like 'initialInputs' and 'Builder'.
121+ data Observer = Observer
122+ { -- | Observer variant name (e.g. @\"nodetonode\"@). Non-empty.
123+ observerType :: ! String
124+ -- | Opaque params object for the variant.
125+ , observerParams :: ! Aeson. Value
126+ }
127+ deriving (Show , Eq )
128+
129+ instance Aeson. FromJSON Observer where
130+ parseJSON = Aeson. withObject " Observer" $ \ o -> do
131+ ty <- o .: " type" :: Aeson.Types. Parser String
132+ when (null ty) $ fail " Observer: \" type\" must be non-empty"
133+ Observer ty <$> o .: " params"
101134
102135--------------------------------------------------------------------------------
103136
@@ -111,14 +144,40 @@ data Builder = Builder
111144 builderType :: ! String
112145 -- | Opaque params object for the variant.
113146 , builderParams :: ! Aeson. Value
147+ -- | Optional recycle strategy. 'Nothing' means no recycling.
148+ , builderRecycle :: ! (Maybe RecycleStrategy )
114149 }
115150 deriving (Show , Eq )
116151
117152instance Aeson. FromJSON Builder where
118153 parseJSON = Aeson. withObject " Builder" $ \ o -> do
119154 ty <- o .: " type" :: Aeson.Types. Parser String
120- when (null ty) $ fail " Builder: type must be non-empty"
155+ when (null ty) $ fail " Builder: \" type\" must be non-empty"
121156 Builder ty <$> o .: " params"
157+ <*> o .:? " recycle"
158+
159+ --------------------------------------------------------------------------------
160+
161+ -- | When to recycle transaction outputs back to the input queue.
162+ data RecycleStrategy
163+ -- | Recycle immediately after building, before entering the payload queue.
164+ = RecycleOnBuild
165+ -- | Recycle when a worker fetches the payload from the queue.
166+ | RecycleOnPull
167+ -- | Recycle when an observer confirms the payload. Carries the observer name.
168+ | RecycleOnConfirm ! String
169+ deriving (Show , Eq )
170+
171+ instance Aeson. FromJSON RecycleStrategy where
172+ parseJSON = Aeson. withObject " RecycleStrategy" $ \ o -> do
173+ ty <- o .: " type" :: Aeson.Types. Parser String
174+ case ty of
175+ " on_build" -> pure RecycleOnBuild
176+ " on_pull" -> pure RecycleOnPull
177+ " on_confirm" ->
178+ RecycleOnConfirm <$> o .: " params"
179+ _ -> fail $ " RecycleStrategy: unknown \" type\" " ++ show ty
180+ ++ " , expected \" on_build\" , \" on_pull\" , or \" on_confirm\" "
122181
123182--------------------------------------------------------------------------------
124183
@@ -186,7 +245,7 @@ parseRateLimit scopeParser = Aeson.withObject "RateLimit" $ \o -> do
186245 rl <- TokenBucket <$> p .: " tps"
187246 pure (maybeScope, rl)
188247 _ -> fail $
189- " RateLimit: unknown type " ++ show ty ++ " , expected \" token_bucket\" "
248+ " RateLimit: unknown \" type\" " ++ show ty ++ " , expected \" token_bucket\" "
190249
191250parseTopLevelRateLimit :: Aeson. Value
192251 -> Aeson.Types. Parser (Maybe TopLevelScope , RateLimit )
@@ -242,8 +301,9 @@ data Workload = Workload
242301 , maybeMaxBatchSize :: ! (Maybe Natural )
243302 -- | Optional on-exhaustion behaviour.
244303 , maybeOnExhaustion :: ! (Maybe OnExhaustion )
245- -- | Targets keyed by name. Duplicate target names are silently discarded
246- -- (last value wins) because Aeson decodes JSON objects into a 'Map'.
304+ -- | Targets keyed by name.
305+ -- Because Aeson decodes JSON objects into a 'Map', duplicate target names
306+ -- are silently discarded (last value wins).
247307 , targets :: ! (Map String Target )
248308 }
249309 deriving (Show , Eq )
@@ -252,7 +312,8 @@ instance Aeson.FromJSON Workload where
252312 parseJSON = Aeson. withObject " Workload" $ \ o ->
253313 Workload
254314 <$> o .:? " builder"
255- <*> Aeson.Types. explicitParseFieldMaybe parseWorkloadRateLimit o " rate_limit"
315+ <*> Aeson.Types. explicitParseFieldMaybe parseWorkloadRateLimit o
316+ " rate_limit"
256317 <*> o .:? " max_batch_size"
257318 <*> o .:? " on_exhaustion"
258319 <*> o .: " targets"
0 commit comments