Skip to content

Latest commit

 

History

History
232 lines (142 loc) · 7.46 KB

DSL:-Ash.Notifier.PubSub.md

File metadata and controls

232 lines (142 loc) · 7.46 KB

DSL: Ash.Notifier.PubSub

A builtin notifier to help you publish events over any kind of pub-sub tooling.

This is plug and play with Phoenix.PubSub, but could be used with any pubsub system.

You configure a module that defines a broadcast/3 function, and then add some "publications" which configure under what conditions an event should be sent and what the topic should be.

Debugging PubSub

It can be quite frustrating when setting up pub_sub when everything appears to be set up properly, but you aren't receiving events. This usually means some kind of mismatch between the event names produced by the resource/config of your publications, and you can use the following flag to display debug information about all pub sub events.

config :ash, :pub_sub, debug?: true

Topic Templates

Often you want to include some piece of data in the thing being changed, like the :id attribute. This is done by providing a list as the topic, and using atoms which will be replaced by their corresponding values. They will ultimately be joined with :.

For example:

prefix "user"

publish :create, ["created", :user_id]

This might publish a message to "user:created:1" for example.

For updates, if the field in the template is being changed, a message is sent to both values. So if you change user 1 to user 2, the same message would be published to user:updated:1 and user:updated:2. If there are multiple attributes in the template, and they are all being changed, a message is sent for every combination of substitutions.

Important

If the previous value was nil or the field was not selected on the data passed into the action, then a notification is not sent for the previous value.

If the new value is nil then a notification is not sent for the new value.

Template parts

Templates may contain lists, in which case all combinations of values in the list will be used. Add nil to the list if you want to produce a pattern where that entry is omitted.

The atom :_tenant may be used. If the changeset has a tenant set on it, that value will be used, otherwise that combination of values is ignored.

The atom :_pkey may be used. It will be a stringified, concatenation of the primary key fields, or just the primary key if there is only one primary key field.

The atom nil may be used. It only makes sense to use it in the context of a list of alternatives, and adds a pattern where that part is skipped.

publish :updated, [[:team_id, :_tenant], "updated", [:id, nil]]

Would produce the following messages, given a team_id of 1, a tenant of org_1, and an id of 50:

"1:updated:50"
"1:updated"
"org_1:updated:50"
"org_1:updated"

Custom Delimiters

It's possible to change the default delimiter used when generating topics. This is useful when working with message brokers like RabbitMQ, which rely on a different set of delimiters for routing.

pub_sub do
  delimiter "."
end

Named Pubsub modules

If you are using a phoenix Endpoint module for pubsub then this is unnecessary. If you want to use a custom pub sub started with something like {Phoenix.PubSub, name: MyName}, then you can provide MyName to here.

Broadcast Types

Configured with broadcast_type.

  • :notification just sends the notification
  • :phoenix_broadcast sends a %Phoenix.Socket.Broadcast{} (see above)
  • :broadcast sends %{topic: (topic), event: (event), notification: (notification)}

pub_sub

A section for configuring how resource actions are published over pubsub

Nested DSLs

Examples

pub_sub do
  module MyEndpoint
  prefix "post"

  publish :destroy, ["foo", :id]
  publish :update, ["bar", :name] event: "name_change"
  publish_all :create, "created"
end

Options

Name Type Default Docs
module{: #pub_sub-module .spark-required} atom The module to call broadcast/3 on e.g module.broadcast(topic, event, message).
prefix{: #pub_sub-prefix } String.t A prefix for all pubsub messages, e.g users. A message with created would be published as users:created
delimiter{: #pub_sub-delimiter } String.t A delimiter for building topics. Default is a colon (:)
broadcast_type{: #pub_sub-broadcast_type } :notification | :phoenix_broadcast | :broadcast :notification What shape the event payloads will be in. See
name{: #pub_sub-name } atom A named pub sub to pass as the first argument to broadcast.

pub_sub.publish

publish action, topic

Configure a given action to publish its results over a given topic.

Examples

publish :create, "created"
publish :assign, "assigned"

Arguments

Name Type Default Docs
action{: #pub_sub-publish-action .spark-required} atom The name of the action that should be published
topic{: #pub_sub-publish-topic .spark-required} any The topic to publish

Options

Name Type Default Docs
previous_values?{: #pub_sub-publish-previous_values? } boolean false Whether or not to publish messages with both the new values and the old values for referencing changed attributes
event{: #pub_sub-publish-event } String.t The name of the event to publish. Defaults to the action name
dispatcher{: #pub_sub-publish-dispatcher } atom The module to use as a dispatcher. If none is set, the pubsub module provided is used.

Introspection

Target: Ash.Notifier.PubSub.Publication

pub_sub.publish_all

publish_all type, topic

Works the same as publish, except that it takes a type and publishes all actions of that type.

Examples

publish_all :create, "created"

Arguments

Name Type Default Docs
type{: #pub_sub-publish_all-type } :create | :update | :destroy Publish on all actions of a given type
topic{: #pub_sub-publish_all-topic .spark-required} any The topic to publish

Options

Name Type Default Docs
action{: #pub_sub-publish_all-action } atom The name of the action that should be published
previous_values?{: #pub_sub-publish_all-previous_values? } boolean false Whether or not to publish messages with both the new values and the old values for referencing changed attributes
event{: #pub_sub-publish_all-event } String.t The name of the event to publish. Defaults to the action name
dispatcher{: #pub_sub-publish_all-dispatcher } atom The module to use as a dispatcher. If none is set, the pubsub module provided is used.

Introspection

Target: Ash.Notifier.PubSub.Publication

<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>