Module: HotCell::Payload
- Defined in:
- lib/hot_cell/payload.rb
Overview
A payload is a JSON object, and the rules are stricter than JSON's in one direction and looser in another.
Values must be JSON-native, because to_json is not a check. It serializes a Symbol to a String, a Time to a String, and an arbitrary object through whatever to_json that object happens to define, all silently and none of it faithfully. So validate the values, then serialize.
Keys may be Strings or Symbols, because both serialize to the same JSON string and both arrive
symbolized. { format: "png" } is how a payload is naturally written and must not be rejected.
Constant Summary collapse
- MAX_DEPTH =
A payload sits one level inside the message envelope, so it gets one level less than the line.
MAX_NESTING - 1
Class Method Summary collapse
- .generate(object, name) ⇒ Object
-
.parse(json) ⇒ Object
Keys are symbolized so operations read payload and can splat a nested hash into keyword arguments.
- .validate!(object, name) ⇒ Object
Class Method Details
.generate(object, name) ⇒ Object
20 21 22 23 |
# File 'lib/hot_cell/payload.rb', line 20 def generate(object, name) validate! object, name JSON.generate object end |
.parse(json) ⇒ Object
Keys are symbolized so operations read payload and can splat a nested hash into keyword arguments. Values are not: a Symbol would not survive the round trip, which the JSON-native rule already forbids.
One rescue for the whole JSON layer. Naming what JSON.parse raises has been wrong twice: a report that was not an object raised TypeError past a rescue for JSON::ParserError, and a key holding invalid UTF-8 raised EncodingError past both. The supervisor parses worker reports inside its deadline loop with nothing above it rescuing, so each miss denies service to every request in the cell.
The body is one JSON.parse call, so the rescue cannot hide a bug of our own. NoMemoryError is not a StandardError and stays uncaught: a document that large is the worker's memory verdict, not a bad line.
38 39 40 41 42 |
# File 'lib/hot_cell/payload.rb', line 38 def parse(json) JSON.parse json, symbolize_names: true, max_nesting: MAX_NESTING, allow_nan: false rescue StandardError => error raise MessageError, "#{error.class}: #{Failure.sanitize(error.)}" end |
.validate!(object, name) ⇒ Object
44 45 46 47 48 49 50 51 |
# File 'lib/hot_cell/payload.rb', line 44 def validate!(object, name) unless object.is_a?(Hash) raise SerializationError, "#{name} is a #{object.class} and must be a Hash" end walk object, name, 1 object end |