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
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
...
- 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
...
- When I update the
Users
table with a new randompoints
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.