Skip to content

Instantly share code, notes, and snippets.

@josevalim
Created April 9, 2014 08:58
Show Gist options
  • Select an option

  • Save josevalim/10244117 to your computer and use it in GitHub Desktop.

Select an option

Save josevalim/10244117 to your computer and use it in GitHub Desktop.

Revisions

  1. José Valim created this gist Apr 9, 2014.
    63 changes: 63 additions & 0 deletions 1_gen_server.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    defmodule Mix.TasksServer do
    @moduledoc false
    use GenServer.Behaviour

    def start_link() do
    :gen_server.start_link({ :local, __MODULE__ }, __MODULE__, :ok, [])
    end

    def clear_tasks() do
    call :clear_tasks
    end

    def run_task(task, proj) do
    call { :run_task, task, proj }
    end

    def put_task(task, proj) do
    cast { :put_task, task, proj }
    end

    def delete_task(task, proj) do
    cast { :delete_task, task, proj }
    end

    defp call(arg) do
    :gen_server.call(__MODULE__, arg, 30_000)
    end

    defp cast(arg) do
    :gen_server.cast(__MODULE__, arg)
    end

    ## Callbacks

    def init(:ok) do
    { :ok, HashSet.new }
    end

    def handle_call(:clear_tasks, _from, set) do
    { :reply, set, HashSet.new }
    end

    def handle_call({ :run_task, task, proj }, _from, set) do
    item = { task, proj }
    { :reply, not(item in set), Set.put(set, item) }
    end

    def handle_call(request, from, config) do
    super(request, from, config)
    end

    def handle_cast({ :put_task, task, proj }, set) do
    { :noreply, Set.put(set, { task, proj }) }
    end

    def handle_cast({ :delete_task, task, proj }, set) do
    { :noreply, Set.delete(set, { task, proj }) }
    end

    def handle_cast(request, config) do
    super(request, config)
    end
    end
    36 changes: 36 additions & 0 deletions 2_agent.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    defmodule Mix.TasksServer do
    @moduledoc false

    def start_link() do
    Agent.start_link(fn -> HashSet.new end, local: __MODULE__)
    end

    def clear_tasks() do
    get_and_update fn set ->
    { set, HashSet.new }
    end
    end

    def run_task(task, proj) do
    item = { task, proj }
    get_and_update fn set ->
    { not(item in set), Set.put(set, item) }
    end
    end

    def put_task(task, proj) do
    update &Set.put(&1, { task, proj })
    end

    def delete_task(task, proj) do
    update &Set.delete(&1, { task, proj })
    end

    defp get_and_update(fun) do
    Agent.get_and_update(__MODULE__, fun, 30_000)
    end

    defp update(fun) do
    Agent.update(__MODULE__, fun)
    end
    end