Skip to content

Instantly share code, notes, and snippets.

@josevalim
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josevalim/b069778cf39c7b4c646f to your computer and use it in GitHub Desktop.
Save josevalim/b069778cf39c7b4c646f to your computer and use it in GitHub Desktop.
defmodule Rotor do
@doc """
Starts a new rotor as part of a supervision tree.
## Options
* `:name` - the registered name of the rotor
"""
def start_link(paths, opts) do
Rotor.Supervisor.start_link(paths, opts)
end
@doc """
Subscribes to a given rotor.
"""
def subscribe(rotor, fun) do
spawn_link(fn ->
GenEvent.stream(manager_for(rotor)) |> Enum.each(fun)
end)
end
@doc """
Returns the manager for a given rotor.
"""
def manager_for(rotor) do
case List.keyfind(Supervisor.which_children(rotor), :manager, 0) do
{:manager, pid, _, _} when is_pid(pid) -> pid
end
end
end
defmodule Rotor.Supervisor do
use Supervisor
def start_link(paths, opts) do
Supervisor.start_link(__MODULE__, {paths, opts}, Keyword.take(opts, [:name]))
end
def init({paths, _opts}) do
children = [
worker(GenEvent, [], id: :manager),
worker(Rotor.Watcher, [self(), paths], id: :watcher)
]
supervise(children, strategy: :one_for_one)
end
end
defmodule Rotor.Watcher do
def start_link(sup, paths) do
Task.start_link(fn -> watch(sup, paths) end)
end
defp watch(sup, paths) do
GenEvent.notify Rotor.manager_for(sup), changed_files(paths)
wait_until_change()
watch(sup, paths)
end
# Here is where you will calculate the available files
defp changed_files(paths) do
paths |> Enum.flat_map(&Path.wildcard/1) |> Enum.uniq
end
# Here is where you wait until there is a change
defp wait_until_change() do
:timer.sleep(1000)
end
end
# Sample run
{:ok, _} = Rotor.start_link(["*", "mix.exs"], name: :stylesheets)
Rotor.subscribe :stylesheets, fn files ->
IO.inspect files
end
# Sleep this process since the subscription runs in other processes
:timer.sleep(:infinity)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment