benthosdev / benthos

Fancy stream processing made operationally mundane
https://www.benthos.dev
MIT License
7.68k stars 752 forks source link

Cache Memory only works with numbers #2536

Closed danriedl closed 3 weeks ago

danriedl commented 3 weeks ago

I did expect that the memory cache_resource works with maps/lists/strings. Somehow it only works if the provided value is a number or a number as string.

This works:

input:
  generate:
    mapping: |
      root = {}
pipeline:
  processors:
    - branch:
        processors:
          - cache:
              resource: stringstore
              operator: get
              key: name
        result_map: 'root.name = this'
output:
  stdout: {}
cache_resources:
  - label: stringstore
    memory:
      init_values:
        name: "0"
INFO Running main config from specified file       @service=benthos benthos_version=v4.26.0 path=/benthos.yaml
INFO Launching a benthos instance, use CTRL+C to close  @service=benthos
INFO Listening for HTTP requests at: http://0.0.0.0:4195  @service=benthos
{"name":0}

And this does not work:

input:
  generate:
    mapping: |
      root = {}
pipeline:
  processors:
    - branch:
        processors:
          - cache:
              resource: stringstore
              operator: get
              key: name
        result_map: 'root.name = this'
output:
  stdout: {}
cache_resources:
  - label: stringstore
    memory:
      init_values:
        name: "dan"
INFO Running main config from specified file       @service=benthos benthos_version=v4.26.0 path=/benthos.yaml
INFO Listening for HTTP requests at: http://0.0.0.0:4195  @service=benthos
INFO Launching a benthos instance, use CTRL+C to close  @service=benthos
ERRO Branch error: result mapping failed: failed assignment (line 1): unable to reference message as structured (with 'this'): parse as json: invalid character 'd' looking for beginning of value  @service=benthos label="" path=root.pipeline.processors.0
{}

Is it a bug or a feature?

Thanks in advance!

mihaitodor commented 3 weeks ago

Hey @danriedl 👋 It's by design. Values in caches are stored as bytes, so this will throw an error if the data it gets isn't something that can be parsed using a JSON parser. What you want to use there is root.name = content().string(). The .string() part is needed because otherwise the data in that name field will get serialised back to JSON using base64 encoding.

mihaitodor commented 3 weeks ago

Hey @danriedl 👋 It's by design. Values in caches are stored as bytes, so this will throw an error if the data it gets isn't something that can be parsed using a JSON parser. What you want to use there is root.name = content().string(). The .string() part is needed because otherwise the data in that name field will get serialised back to JSON using base64 encoding.

PS: Converting this to a discussion as per #2026.