Last active
August 29, 2015 14:02
-
-
Save josevalim/b069778cf39c7b4c646f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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