Skip to content

Instantly share code, notes, and snippets.

@c-j-j
Created February 28, 2016 16:43
Show Gist options
  • Save c-j-j/2341c2bd1272d48f4857 to your computer and use it in GitHub Desktop.
Save c-j-j/2341c2bd1272d48f4857 to your computer and use it in GitHub Desktop.
Concurrent file searcher in Elixir
defmodule CatFinder do
def find(scheduler) do
send scheduler, {:ready, self}
receive do
{ :find, file, scheduler_pid} ->
send scheduler_pid, { :answer, file, num_of_cats(file) }
find(scheduler)
{ :shutdown } ->
exit(:normal)
end
end
defp num_of_cats(file) do
Regex.scan(~r/cat/, File.read!(file)) |> length
end
end
defmodule Scheduler do
def run(files) do
files
|> Enum.map(fn(_) -> spawn(CatFinder, :find, [self]) end)
|> schedule_processes(files, [])
end
defp schedule_processes(processes, files, results) do
receive do
{:ready, pid} when length(files) > 0 ->
[ next | tail ] = files
send pid, {:find, next, self}
schedule_processes(processes, tail, results)
{:ready, pid} ->
send pid, {:shutdown}
if length(processes) > 1 do
schedule_processes(List.delete(processes, pid), files, results)
else
results
end
{:answer, file, num_of_cats} ->
schedule_processes(processes, files, [ {file, num_of_cats} | results ])
end
end
end
File.cd!("test_files")
files = File.ls!
results = Scheduler.run(files)
IO.puts(inspect results)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment