From 12bf5ce335282ba20afac4c1cbdda65a14f769b2 Mon Sep 17 00:00:00 2001 From: Joel Abshier Date: Mon, 4 Oct 2021 15:02:29 -0500 Subject: [PATCH] Move actvity monitoring state into a `GenSever` and add calls from each GQL field --- lib/gql_preferences/activity.ex | 26 --------- lib/gql_preferences/activity_monitor.ex | 7 +-- lib/gql_preferences/activity_server.ex | 18 +++++++ lib/gql_preferences/application.ex | 4 +- lib/gql_preferences_web/resolvers/activity.ex | 6 +++ .../resolvers/preferences.ex | 10 ++++ lib/gql_preferences_web/resolvers/users.ex | 36 ++++++++----- lib/gql_preferences_web/schema.ex | 54 +++++++++++-------- 8 files changed, 95 insertions(+), 66 deletions(-) delete mode 100644 lib/gql_preferences/activity.ex create mode 100644 lib/gql_preferences/activity_server.ex create mode 100644 lib/gql_preferences_web/resolvers/activity.ex diff --git a/lib/gql_preferences/activity.ex b/lib/gql_preferences/activity.ex deleted file mode 100644 index 99a1fd3..0000000 --- a/lib/gql_preferences/activity.ex +++ /dev/null @@ -1,26 +0,0 @@ -defmodule ActivityServer do - use GenServer - - def start_link(_), do: GenServer.start_link(__MODULE__, %{}, name: ActivityServer) - def init(_), do: {:ok, %{}} - - def handle_cast({:update, key}, state) do - case Map.has_key?(state, key) do - true -> - {:noreply, Map.update(state, key, 1, fn {k, v} -> {k, v + 1} end)} - - _ -> - {:noreply, Map.put(state, key, 1)} - end - end - - def handle_call({:get, key}, state) do - case Map.has_key?(state, key) do - true -> - {:reply, {:ok, Map.get(state, key)}, state} - - _ -> - {:reply, {:error, "Requested "}, state} - end - end -end diff --git a/lib/gql_preferences/activity_monitor.ex b/lib/gql_preferences/activity_monitor.ex index 9d207cf..0201f87 100644 --- a/lib/gql_preferences/activity_monitor.ex +++ b/lib/gql_preferences/activity_monitor.ex @@ -1,5 +1,6 @@ defmodule ActivityMonitor do - @activity_server GenServer.whereis(ActivityServer) - def update_resolver_activity(key), do: @activity_server |> GenServer.cast({:update, key}) - def fetch_resolver_activity(key), do: @activity_server |> GenServer.call({:get, key}) + def update_resolver_activity(key), do: context() |> GenServer.cast({:update, key}) + def fetch_resolver_activity(key), do: context() |> GenServer.call({:get, key}) + + defp context(), do: GenServer.whereis(ActivityServer) end diff --git a/lib/gql_preferences/activity_server.ex b/lib/gql_preferences/activity_server.ex new file mode 100644 index 0000000..57c07ae --- /dev/null +++ b/lib/gql_preferences/activity_server.ex @@ -0,0 +1,18 @@ +defmodule ActivityServer do + use GenServer + + def start_link(_), do: GenServer.start_link(__MODULE__, %{}, name: ActivityServer) + def init(_), do: {:ok, %{}} + + def handle_cast({:update, key}, state) do + {:noreply, Map.update(state, key, 1, &(&1 + 1))} + end + + def handle_call({:get, key}, _from, state) do + if Map.has_key?(state, key) do + {:reply, {:ok, Map.get(state, key)}, state} + else + {:reply, {:error, "Requested key: #{key} is invalid"}, state} + end + end +end diff --git a/lib/gql_preferences/application.ex b/lib/gql_preferences/application.ex index 3eca66d..c1fd252 100644 --- a/lib/gql_preferences/application.ex +++ b/lib/gql_preferences/application.ex @@ -4,6 +4,7 @@ defmodule UserPreferences.Application do @moduledoc false use Application + alias ActivityServer @impl true def start(_type, _args) do @@ -15,9 +16,10 @@ defmodule UserPreferences.Application do # Start the PubSub system {Phoenix.PubSub, name: UserPreferences.PubSub}, # Start the Endpoint (http/https) - UserPreferencesWeb.Endpoint + UserPreferencesWeb.Endpoint, # Start a worker by calling: UserPreferences.Worker.start_link(arg) # {UserPreferences.Worker, arg} + ActivityServer ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/lib/gql_preferences_web/resolvers/activity.ex b/lib/gql_preferences_web/resolvers/activity.ex new file mode 100644 index 0000000..0c2f841 --- /dev/null +++ b/lib/gql_preferences_web/resolvers/activity.ex @@ -0,0 +1,6 @@ +defmodule UserPreferencesWeb.Resolvers.Activity do + def get_activity(_, args, _) do + ActivityMonitor.update_resolver_activity("get_activity") + ActivityMonitor.fetch_resolver_activity(args.key) + end +end diff --git a/lib/gql_preferences_web/resolvers/preferences.ex b/lib/gql_preferences_web/resolvers/preferences.ex index 6ae07e7..26157a6 100644 --- a/lib/gql_preferences_web/resolvers/preferences.ex +++ b/lib/gql_preferences_web/resolvers/preferences.ex @@ -2,12 +2,22 @@ defmodule UserPreferencesWeb.Resolvers.Preferences do alias UserPreferences.{Repo, Preferences} def get_preferences(parent, _args, _) do + ActivityMonitor.update_resolver_activity("get_preferences") + Preferences |> Repo.get_by(user_id: parent.id) |> then(&{:ok, &1}) end + def create_preferences(args) do + %Preferences{} + |> Preferences.changeset(args) + |> Repo.insert() + end + def update_preferences_by_id(_, args, _) do + ActivityMonitor.update_resolver_activity("update_preferences_by_id") + Repo.get_by(Preferences, user_id: args.user_id) |> Preferences.changeset(args) |> Repo.update() diff --git a/lib/gql_preferences_web/resolvers/users.ex b/lib/gql_preferences_web/resolvers/users.ex index 64428f3..b378401 100644 --- a/lib/gql_preferences_web/resolvers/users.ex +++ b/lib/gql_preferences_web/resolvers/users.ex @@ -1,28 +1,34 @@ defmodule UserPreferencesWeb.Resolvers.Users do - alias UserPreferences.{Repo, User, Preferences} + alias UserPreferences.{Repo, User} + alias UserPreferencesWeb.Resolvers - def get_user_by_id(_parent, args, _res), do: {:ok, Repo.get(User, args.id)} + def get_user_by_id(_parent, args, _res) do + ActivityMonitor.update_resolver_activity("get_user_by_id") + {:ok, Repo.get(User, args.id)} + end + + def get_all_users(_, args, _) do + ActivityMonitor.update_resolver_activity("get_all_users") - def get_all_users(_, args, _), - do: - Absinthe.Relay.Connection.from_query( - User, - &Repo.all/1, - args - ) + Absinthe.Relay.Connection.from_query( + User, + &Repo.all/1, + args + ) + end def create_user(_parent, args, _res) do + ActivityMonitor.update_resolver_activity("create_user") + {:ok, user} = %User{} |> User.changeset(args) |> Repo.insert() - pref_args = Map.put(args.preferences, :user_id, user.id) - {:ok, pref} = - %Preferences{} - |> Preferences.changeset(pref_args) - |> Repo.insert() + args.preferences + |> Map.put(:user_id, user.id) + |> Resolvers.Preferences.create_preferences() res = Map.put(user, :preferences, pref) @@ -30,6 +36,8 @@ defmodule UserPreferencesWeb.Resolvers.Users do end def update_user(_, args, _) do + ActivityMonitor.update_resolver_activity("update_user") + Repo.get(User, args.id) |> User.changeset(args) |> Repo.update() diff --git a/lib/gql_preferences_web/schema.ex b/lib/gql_preferences_web/schema.ex index 826162d..6768357 100644 --- a/lib/gql_preferences_web/schema.ex +++ b/lib/gql_preferences_web/schema.ex @@ -5,34 +5,17 @@ defmodule UserPreferencesWeb.Schema do alias UserPreferencesWeb.Resolvers - connection(node_type: :user) - - node interface do - resolve_type(fn - %UserPreferences.User{}, _ -> - :user - - _, _ -> - nil - end) - end - query do - node field do - resolve(fn - %{type: :user, id: local_id}, _ -> - {:ok, UserPreferences.Repo.get(UserPreferences.User, local_id)} - - _, _ -> - {:error, "Unknown node"} |> IO.inspect() - end) - end - field :user, :user do arg(:id, non_null(:id)) resolve(&Resolvers.Users.get_user_by_id/3) end + field :resolver_hits, :integer do + arg(:key, non_null(:string)) + resolve(&Resolvers.Activity.get_activity/3) + end + connection field :users, node_type: :user do arg(:before, :integer) arg(:after, :integer) @@ -42,6 +25,16 @@ defmodule UserPreferencesWeb.Schema do arg(:likes_phone_calls, :boolean) resolve(&Resolvers.Users.get_all_users/3) end + + node field do + resolve(fn + %{type: :user, id: local_id}, _ -> + {:ok, UserPreferences.Repo.get(UserPreferences.User, local_id)} + + _, _ -> + {:error, "Unknown node"} |> IO.inspect() + end) + end end mutation do @@ -67,6 +60,18 @@ defmodule UserPreferencesWeb.Schema do end end + connection(node_type: :user) + + node interface do + resolve_type(fn + %UserPreferences.User{}, _ -> + :user + + _, _ -> + nil + end) + end + node object(:user) do field :id, :id field :name, :string @@ -84,6 +89,11 @@ defmodule UserPreferencesWeb.Schema do field :likes_phone_calls, :boolean end + node object(:resolver_hits) do + field :key, :string + field :hits, :integer + end + input_object :preferences_input do field :likes_emails, non_null(:boolean) field :likes_phone_calls, non_null(:boolean)