Skip to content

Instantly share code, notes, and snippets.

@lukeledet
Last active May 19, 2020 15:48
Show Gist options
  • Save lukeledet/54baccfb69d26304c61dda7a2222bf66 to your computer and use it in GitHub Desktop.
Save lukeledet/54baccfb69d26304c61dda7a2222bf66 to your computer and use it in GitHub Desktop.
Compile notifications
defmodule Mix.Tasks.Compile.Notifications do
@moduledoc """
Send notifications when compiling is done
Uses a GenServer to limit the number of notifications it sends to one every
@notification_timeout_ms milliseconds. This is because phoenix checks if any
files need to be compiled on every request.
Setup:
* Put this in lib/mix/tasks/compile
* add :notifications to the end of the list of compilers in mix.exs
* add :notifications to the end of the list of reloadable_compilers in config/dev.exs
* install noti if you want system notifications
"""
use Mix.Task
use GenServer
@notification_timeout_ms 10_000
@doc """
This is called when the compiler runs
"""
def run(_args) do
case GenServer.start(__MODULE__, [], name: __MODULE__) do
{:ok, pid} ->
send(pid, :queue_notification)
{:error, {:already_started, pid}} ->
send(pid, :queue_notification)
error ->
IO.inspect(error)
IO.puts("Error starting compiler notifications")
end
IO.puts("Compile complete.")
:ok
end
def init(args) do
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:ok, args}
end
# Sets the state to :ok meaning it should send notifications
def handle_info(:queue_notification, _state) do
{:noreply, :ok}
end
# when the state is nil, notifications should not be sent
def handle_info(:send_notifications, nil) do
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:noreply, nil}
end
# send notifications then set the state to nil
def handle_info(:send_notifications, :ok) do
# this is in a task because afplay blocks for about 1.1 seconds
Task.start_link(fn ->
System.cmd("afplay", ["/Applications/Slack.app/Contents/Resources/confirm_delivery.mp3"])
end)
{:ok, application_name} = :application.get_application(__MODULE__)
System.cmd("noti", ["-t", to_string(application_name), "-m", "Compile complete"])
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:noreply, nil}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment