Some Late Changes - abarr/remote GitHub Wiki

Last night I was thinking about the GenServer and how (Based on the requirements and my assumptions) it owns and controls the User data. Because the only thing that changes between a schedule points update and the timestamp for a call, there is no need to query the database to build the results. This morning I made the following changes.

  1. I added a new attribute to the GenServer state that represents the result of the query
"/lib/remote/users/user_server.ex"

...
@impl true
def init(config) do
  schedule_update(config.update_interval)
  {:ok, {%{max_number: Enum.random(0..100), timestamp: nil}, config, []}} # Added an initial empty list
end
...
  1. I updated the handle_call/3 to match the cache element of the state; if the cache is marked empty, it runs the query to get the new points value

...
def handle_call(:get_users_points_greater_than_max, _from, {state, config, :empty}) do
  max_num = state.max_number
  limit = config.users_returned_limit
  users = BuildQuery.list_users_by(max_num, limit)
  result = {:ok, %{users: users, timestamp: state.timestamp}}

  {:reply, result, {%{state | timestamp: DateTime.utc_now()}, config, users}}
end

def handle_call(:get_users_points_greater_than_max, _from, {state, config, user_cache}) do
  result = {:ok, %{ users: user_cache, timestamp: state.timestamp}}
  {:reply, result, {%{state | timestamp: DateTime.utc_now()}, config, user_cache}}
end
...
  1. When I update the Users table with a new random points value, I mark the cache as :empty in the state
"/lib/remote/users/user_server.ex"

...
@impl true
def handle_info(:update_user_points, {state, config, _}) do
  case BuildQuery.update_all_users_points(config.max_num_range, config.min_num_range) do
    :ok ->
      schedule_update(config.update_interval)
      {:noreply, {%{state | max_number: Enum.random(0..100)}, config, :empty}}

    _error ->
      raise "User points update failed!"
  end
end
...

With those changes, my tests ran and passed, and I was able to run the manual tests and confirm that they worked as planned. The benefits of this approach are that the update task will not ever hold up the API.