EctoSync (EctoSync v0.4.0)
View SourceA Cache updater and router for events emitted when database entries are updated. Subscribers can provide a list of records that they want to receive updates on. Additionally, they can provide a function that will act as a means of authorization on the updates they should get.
Using the subscribe function a process can subscribe to all messages for a given struct.
Summary
Functions
Returns a specification to start this module under a supervisor.
Gets a value from cache.
Determines whether or not the event was sent by this process
Starts EctoSync.
Subscribe to Ecto.Schema(s) provided. The input can be one of following
Returns a list of pids that are subscribed to the given watcher identifier.
Performs the actual syncing of a given value. Based on the input and the event, certain behaviour can be expected.
Unsubscribe the current process from events. Possible inputs are
Create watcher specifications for a given schema.
Types
@type schema_or_list_of_schemas() :: Ecto.Schema.t() | [Ecto.Schema.t()]
@type subscriptions() :: [{EctoWatch.watcher_identifier(), term()}]
@type syncable() :: term() | Ecto.Schema.t() | [Ecto.Schema.t()]
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Gets a value from cache.
See sync/3 for options available.
Determines whether or not the event was sent by this process
Starts EctoSync.
Options
:cache_name, the name of the cache that used to cache changes:repo, the repo to track changes in.:watchers, a list of watchers that EctoSync will pass on to EctoWatch.:pub_sub, the PubSub module to use for sending events, defaults to:ecto_sync_pub_sub.
@spec subscribe(schema_or_list_of_schemas() | EctoWatch.watcher_identifier(), list()) :: [term()]
Subscribe to Ecto.Schema(s) provided. The input can be one of following:
- an Ecto.Schema struct,
- a list of Ecto.Schema struct,
- an EctoWatch identifier.
When an Ecto.Schema struct or list of structs is provided, the process is subscribed to all :updated and :deleted events for the Ecto.Schema that represents the struct.
Examples
iex> defmodule Test do
...> use Ecto.Schema
...> schema do
...> field :name, :string
...> end
...> end
iex> EctoSync.subscribe(Test)
[{{Test, :inserted}, nil}, {{Test, :updated}, nil}, {{Test, :deleted}, nil}]
iex> EctoSync.subscribe(%Test{id: 1})
[{{Test, :updated}, 1}, {{Test, :deleted}, 1}]
@spec subscriptions(EctoWatch.watcher_identifier(), term()) :: [ {pid(), Registry.value()} ]
Returns a list of pids that are subscribed to the given watcher identifier.
Performs the actual syncing of a given value. Based on the input and the event, certain behaviour can be expected.
:inserted event
| struct | input | output |
|---|---|---|
%Post{id: 1} | [] | [%Post{id: 1}] |
%Post{id: 2} | [%Post{id: 1}] | [%Post{id: 1}, %Post{id: 2}] |
%Comment{id: 1, post_id: 1} | [%Post{id: 1, comments: []}] | [%Post{id: 1, comments: [%Comment{id: 1}]}] |
:updated event
| struct | input | output |
|---|---|---|
%Post{id: 1, name: "Updated name"} | %Post{id:1, name: "Name"} | %Post{id: 1}, name: "Updated name"} |
%Post{id: 2} | [%Post{id: 1}] | [%Post{id: 1}, %Post{id: 2}] |
%Comment{id: 1, post_id: 1} | [%Post{id: 1, comments: []}] | [%Post{id: 1, comments: [%Comment{id: 1}]}] |
%Comment{id: 1, post_id: 2} | [%Post{id: 1, comments: [%Comment{id: 1}]}, %Post{id: 2, comments: []}] | [%Post{id: 1, comments: []}, %Post{id: 2, comments: [%Comment{id: 1}]}] |
:deleted event
| struct | input | output |
|---|---|---|
%Post{id: 1} | [] | [] |
%Post{id: 1} | %Post{id: 1} | %Post{id: 1} |
%Post{id: 2} | [%Post{id: 1}, %Post{id: 2}] | [%Post{id: 1}] |
%Comment{id: 1, post_id: 1} | [%Post{id: 1, comments: [%Comment{id: 1}]}] | [%Post{id: 1, comments: []}] |
@spec unsubscribe( schema_or_list_of_schemas() | EctoSync.Watcher.watcher_identifier(), term() ) :: [ term() ]
Unsubscribe the current process from events. Possible inputs are:
Ecto.Schemastruct- a list of
Ecto.Schemastructs - watcher_identifier tuple and id
Examples
iex> EctoSync.unsubscribe(person)
:ok
iex> EctoSync.unsubscribe([person1, person2])
:ok
iex> EctoSync.unsubscribe({Person, :updated}, 1)
:ok
iex> EctoSync.unsubscribe({Person, :inserted}, nil)
:ok
Create watcher specifications for a given schema.
schema- The Ecto.Schema to subscribe to.
Options
:extra_columns, which extra columns should be included:assocs, a preload like keyword list of associations to subscribe to. If assocs are specified in the options, the necessary extra_columns will be added or merged to the:extra_columnsoption.
Examples
Assuming the same schemas are present as in the Use Cases page.
# Generate events for a schema without associations
watchers(MyApp.User)
# => [
# {MyApp.User, :inserted, []},
# {MyApp.User, :updated, []},
# {MyApp.User, :deleted, []}
# ]
# Generate events for all associations
watchers(User, assocs: [posts: [:comments, :tags, :labels]])
# => Includes events for:
# [
# {Label, :deleted, [extra_columns: []]},
# {Label, :inserted, [extra_columns: []]},
# {Label, :updated, [extra_columns: []]},
# {Person, :deleted, [extra_columns: []]},
# {Person, :inserted, [extra_columns: []]},
# {Person, :updated, [extra_columns: []]},
# {Post, :deleted, [extra_columns: [:person_id]]},
# {Post, :deleted, [extra_columns: [:post_id]]},
# {Post, :inserted, [extra_columns: [:person_id]]},
# {Post, :inserted, [extra_columns: [:post_id]]},
# {Post, :updated, [extra_columns: [:person_id]]},
# {Post, :updated, [extra_columns: [:post_id]]},
# {PostsTags, :deleted, [extra_columns: [:tag_id, :post_id]]},
# {PostsTags, :inserted, [extra_columns: [:tag_id, :post_id]]},
# {PostsTags, :updated, [extra_columns: [:tag_id, :post_id]]},
# {Tag, :deleted, [extra_columns: []]},
# {Tag, :inserted, [extra_columns: []]},
# {Tag, :updated, [extra_columns: []]}
# ]
See watchers/2.