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.
- I added a new attribute to the
GenServerstate 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
...
- I updated the
handle_call/3to 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
...
- When I update the
Userstable with a new randompointsvalue, I mark the cache as:emptyin 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.