Skip to content

Instantly share code, notes, and snippets.

@iantbutler01
Last active February 5, 2020 06:52
Show Gist options
  • Save iantbutler01/573db9616da4ebc109e931f843e58d5a to your computer and use it in GitHub Desktop.
Save iantbutler01/573db9616da4ebc109e931f843e58d5a to your computer and use it in GitHub Desktop.
CrawlerExample.Queue do
use GenServer
#client
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, nil, opts)
end
def load_from_file(file_path) do
GenServer.cast(__MODULE__, {:load_state_from_disk, file_path})
end
def push(url) when is_binary(url) do
GenServer.cast(__MODULE__, {:push, [url, 0]})
end
def push(url, depth) when is_binary(url) and is_integer(depth) do
GenServer.cast(__MODULE__, {:push, [url, depth]})
end
def pop() do
GenServer.call(__MODULE__, :pop)
end
#server
@impl true
def init(_init_arg) do
schedule_write_to_disk(5000)
{:ok, :queue.new}
end
@impl true
def handle_info(:schedule_write_to_disk, state) do
current_state = :queue.to_list(state)
state_json = Poison.encode!(current_state)
File.write("/tmp/crawler_state.json", state_json)
schedule_write_to_disk(interval)
end
@impl true
def handle_cast({:load_state_from_disk, file_path}, _) do
contents = File.read!(file_path)
from_json = Poison.decode!(contents)
{:noreply, :queue.from_list(from_json)}
end
def handle_cast({:push, [url, depth]}, state) do
new_state = :queue.in(state, [url, depth])
{:noreply, new_state}
end
@impl true
def handle_call(:pop, _, state) do
{val, new_queue} = :queue.out(state)
{:reply, val, new_queue}
end
defp schedule_write_to_disk(interval), do: :erlang.send_after(interval, self(), :schedule_write_to_disk)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment