courier v0.1.0 Courier.Scheduler

Scheduler adapter

The Scheduler will allow you to schedule when messages can be sent out. It accomplishes this with four parts

  1. The adapter - needs to be set in the opts
  2. The poller - defaults to an interval of 1_000ms
  3. The store - defaults to Courier.Stores.Simple
  4. The pool - max concurrent deliveries through the adapter at any given time

The Adapter

All Mailers in Courier run through Courier.Scheduler. However, an adapter that scheduled messages are delivering through must be configured. Do this in your environment’s config:

# lib/my_app/mailer.ex
defmodule MyApp.Mailer do
  use Courier, otp_ap: :my_app
end

# config/dev.exs
config :my_app, MyApp.Mailer,
  adapter: Courier.Adapters.Logger

To send mail you just use MyApp.Mailer.deliver/2

Mail.build()
|> MyApp.ScheduledMail.deliver()

Courier will default to sending the email almost instantly. The assumed timestamp when sending is :calendar.universal_time/0. You can tell Courier when the message should be sent by passing the at option

tomorrow =
  :calendar.universal_time()
  |> :calendar.datetime_to_gregorian_seconds()
  |> +(1 * 60 * 60 * 24) # 24 hours in seconds
  |> :calendar.gregorian_seconds_to_datetime()

Mail.build()
|> MyApp.ScheduledMail.deliver(at: tomorrow)

The scheduler will delegate the message sending to the mailer declared in yor Mailer’s opts.

The Poller

The default polling interval is 1_000. This is likely far too aggressive. To change the interval for how frequently the poller awakes to check for new messages to send simply set interval in the opts:

# opts/opts.exs
opts :my_app, MyApp.Mailer,
  adapter: Courier.Adapter.Logger,
  interval: 1_000 * 60 * 60  # awakes once an hour

The value for the interval is in milliseconds in accordance with the value that Process.send_after/3 expects.

Store

The store is where messages are kept until they are ready to be sent. The default store is Courier.Stores.Simple and is just an Agent, storing messages in-memory. This may not be ideal for your use-case. You can override the store in the opts:

# opts/opts.exs
opts :my_app, MyApp.Mailer,
  adapter: MyApp.DefaultMailer,
  store: MyApp.OtherStore

The custom store must respond to a certain API. Please see the documentation for Courier.Store for details or look at the source code for Courier.Stores.Agent.

Pool

The number of concurrent messages being delivered by the adapter is limited with the pooler. By default this number is limited to 10. You can modify this in your environment’s config:

config :my_app, MyApp.Mailer
  adapter: Courier.Adapter.Logger,
  pool_size: 20

If you are sending messages through an external service you should consult the documentation for that service to determine what the max concurrent connections allowed is.

Special Options

These are options that you may want to use in different environment

  • delivery_timeout milliseconds to keep the GenServer alive. This should be set to a much higher value in development and/or test environment.

Summary

Functions

children(opts)