MCPcopy Create free account
hub / github.com/StackStorm/st2 / JSONDictField

Class JSONDictField

st2common/st2common/fields.py:332–510  ·  view source on GitHub ↗

Custom field types which stores dictionary as JSON serialized strings. This is done because storing large objects as JSON serialized strings is much more fficient on the serialize and unserialize paths compared to used EscapedDictField which needs to escape all the special values (

Source from the content-addressed store, hash-verified

330
331
332class JSONDictField(BinaryField):
333 """
334 Custom field types which stores dictionary as JSON serialized strings.
335
336 This is done because storing large objects as JSON serialized strings is much more fficient
337 on the serialize and unserialize paths compared to used EscapedDictField which needs to escape
338 all the special values ($, .).
339
340 Only downside is that to MongoDB those values are plain raw strings which means you can't query
341 on actual dictionary field values. That's not an issue for us, because in places where we use
342 it, those values are already treated as plain binary blobs to the database layer and we never
343 directly query on those field values.
344
345 In micro benchmarks we have seen speed ups for up to 10x on write path and up to 6x on read
346 path. Change also scaled down which means it didn't add any additional overhead for very small
347 results - in fact, it was also faster for small results dictionaries
348
349 More context and numbers are available at https://github.com/StackStorm/st2/pull/4846.
350
351 NOTES, LIMITATIONS:
352
353 This field type can only be used on dictionary values on which we don't perform direct database
354 queries (aka filter on a specific dictionary item value or similar).
355
356 Good examples of those are "result" field on ExecutionDB, LiveActionDB and TaskExecutionDB,
357 "output" on WorkflowExecutionDB, etc.
358
359 IMPLEMENTATION DETAILS:
360
361 If header is used, values are stored in the following format:
362 <compression type>:<serialization type>:<serialized binary data>.
363
364 For example:
365
366 n:o:... - No compression, (or)json serialization
367 z:o:... - Zstandard compression, (or)json serialization
368
369 If header is not used, value is stored as a serialized JSON string of the input dictionary.
370 """
371
372 def __init__(self, *args, **kwargs):
373 # True if we should use field header which is more future proof approach and also allows
374 # us to support optional per-field compression, etc.
375 # This option is only exposed so we can benchmark different approaches and how much overhead
376 # using a header adds.
377 self.use_header = kwargs.pop("use_header", False)
378 self.compression_algorithm = kwargs.pop("compression_algorithm", "none")
379
380 super(JSONDictField, self).__init__(*args, **kwargs)
381
382 def to_mongo(self, value):
383 if not isinstance(value, dict):
384 raise ValueError(
385 "value argument must be a dictionary (got: %s)" % type(value)
386 )
387
388 data = self._serialize_field_value(value)
389 return data

Calls

no outgoing calls