A Bigger Example
Understand the implementation of both tasks and agents through an example.
We'll cover the following...
Rewriting our anagram code
Let’s rewrite our anagram code to use both tasks and an agent.
We’ll load words in parallel from a number of separate dictionaries. A separate task handles each dictionary. We’ll use an agent to store the resulting list of words and signatures.
Press + to interact
defmodule Dictionary do@name __MODULE__### External APIdef start_link,do: Agent.start_link(fn -> %{} end, name: @name)def add_words(words),do: Agent.update(@name, &do_add_words(&1, words))def anagrams_of(word),do: Agent.get(@name, &Map.get(&1, signature_of(word)))### Internal implementationdefp do_add_words(map, words),do: Enum.reduce(words, map, &add_one_word(&1, &2))defp add_one_word(word, map),do: Map.update(map, signature_of(word), [word], &[word|&1])defp signature_of(word),do: word |> to_charlist |> Enum.sort |> to_stringenddefmodule WordlistLoader dodef load_from_files(file_names) dofile_names|> Stream.map(fn name -> Task.async(fn -> load_task(name) end) end)|> Enum.map(&Task.await/1)enddefp load_task(file_name) doFile.stream!(file_name, [], :line)|> Enum.map(&String.trim/1)|> Dictionary.add_wordsendend
Our four wordlist files contain the following:
list1 |
list2 |
list3 |
list4 |
---|---|---|---|
angor |
ester |
palet |
rogan |