Class: AceMQ::AMQP::CompositeCodec

Inherits:
Object
  • Object
show all
Defined in:
lib/acemq/amqp/codec.rb

Overview

Picks a codec by the content type the sender set.

For a queue carrying more than one format — during a migration, or where several producers were written years apart:

codec = CompositeCodec.new(JSONCodec.new, StringCodec.new)

The first codec is what it writes. Reading offers the message to the candidates in order and takes the first that manages it, so order matters where two overlap: put the more specific first, since BytesCodec answers for everything and would win from anywhere in the list.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*codecs) ⇒ CompositeCodec

Returns a new instance of CompositeCodec.

Parameters:

  • codecs (Array<#content_type>) —

    at least one, the first of which is used for writing

Raises:

  • (ArgumentError)


227
228
229
230
231
232
# File 'lib/acemq/amqp/codec.rb', line 227

def initialize(*codecs)
  raise ArgumentError, "a CompositeCodec needs at least one codec" if codecs.empty?

  @codecs = codecs.map { |codec| Codec.check!(codec) }.freeze
  freeze
end

Instance Attribute Details

#codecs ⇒ Array (readonly)

The codecs this one holds, in the order they are tried.

Returns:

  • (Array)


272
273
274
# File 'lib/acemq/amqp/codec.rb', line 272

def codecs
  @codecs
end

Instance Method Details

#can_decode?(content_type) ⇒ Boolean

True when any codec in the set will take it.

Returns:

  • (Boolean)


265
266
267
# File 'lib/acemq/amqp/codec.rb', line 265

def can_decode?(content_type)
  candidates(content_type).any?
end

#content_type ⇒ Object

The first codec's, since that is what gets written.



235
# File 'lib/acemq/amqp/codec.rb', line 235

def content_type = @codecs.first.content_type

#decode(body, content_type = "") ⇒ Object

Reads with the first candidate that manages it.

A content type narrows the candidates to the codecs that claim it. No content type leaves every codec a candidate, because a sender that said nothing has ruled nothing out, and the alternative — guessing one format and failing on the rest — turns a silent producer into a queue of dead letters.

Parameters:

  • body (String)
  • content_type (String) (defaults to: "") —

    what the sender said, or "" when it said nothing

Returns:

  • (Object)

Raises:



253
254
255
256
257
258
259
260
261
262
# File 'lib/acemq/amqp/codec.rb', line 253

def decode(body, content_type = "")
  failures = []
  candidates(content_type).each do |codec|
    return read(codec, body, content_type)
  rescue DecodeError => e
    failures << "#{codec.content_type}: #{e.message}"
  end

  raise DecodeError, describe_failure(content_type, failures)
end

#encode(payload) ⇒ Object

Writes with the first codec.



238
# File 'lib/acemq/amqp/codec.rb', line 238

def encode(payload) = @codecs.first.encode(payload)