# SNS Message Attributes

**EXPERIMENTAL**: This feature is experimental and should not currently be relied upon in event bus subscribers.

## Preface

The Event Bus client library is designed to leave the underlying transport mechanism as somewhat of an implementation detail from the perspective of handling messages. To that extent, the dispatcher logic currently gets everything it cares about from the binary event bus payload. 

The above property allows us to easily move messages to other delivery mechanisms and transports (and also potentially parse messages out of mediums such as archived binary logs, etc). However, it does come with the drawback that it means we get somewhat limited to the subset of capabilities shared across all the transport options.

That said, as our current publishing source is SNS and there are features for SNS subscriptions that could be of use around message attributes, we will experiment with publishing using these attributes.

## Basic Concept

In order to leverage the attributes, we will start ahead of time publishing a handful of well-considered attributes in the event bus publisher. Initially, these attributes will mostly be useful for informational and discovery purposes, but we can perhaps use them for advanced special cases while investigating features that can be built around these attributes.

## Proposed Attributes

All proposed attributes start with prefix `eventbus-` and we recommend all future reified attributes follow this pattern.

### `eventbus-event-type`

**Type**: String

This attribute, when provided, must be the event type name as defined in the `eventbus/schema` library, with the same capitalization, e.g. `UserCreate`, `ClockUpdate`, etc.

The primary use case for this is debugging/inspection of inflight messages, as the event bus clients can currently already disambiguate event types using the binary payload's header, but in the AWS console it would be hard to inspect the binary values. It is also a fairly safe first item to implement.


### `eventbus-rand-e6`

**Type** Number

This attribute is a pseudo-random integer chosen by the publisher client from the range `[0, 1000000)`, iow from `rand.Intn(1e6)` in Go.

The use case for this would be to eventually provide percentage sampling functionality in event bus subscriptions using the numeric range [subscription filter policy](https://docs.aws.amazon.com/sns/latest/dg/sns-subscription-filter-policies.html#numeric-value-matching) like this:

```json
"eventbus-rand-e6": [{"numeric": ["<=", 50000]}]
```

The above filter policy would allow roughly 5% of messages through. The rationale for choosing a number up to 1 million is to allow filters with granularity down to 0.001% to be possible, presuming a high enough message rate, which will handle even topics with several orders of magnitude beyond event bus's current planned max QPS.

Because this filter would throw away all messages not containing this attribute, it would be necessary to start publishing this attribute universally in the library well before building features against the attribute. Early exploration of this feature can be done by manually editing a subscription's filter policy, and then later be integrated into the event bus dashboard GUI to support percentage subscriptions ramp-up in the GUI.

### `eventbus-is-noop`

**Type** Number

This attribute, when provided, can only be set to the value `1`. The existence flags that the message contains a no-op. This potentially allows for filtering no-op messages out of subscriptions either wholesale or on a per-subscription basis in the future.

Like all other attributes, since this only applies to SNS, it means that in the generic case, the mux/dispatcher logic should still filter out no-op messages, it's just a convenience to have.
