Skip to content

Commit

Permalink
Merge pull request #87 from momentohq/runtime-version
Browse files Browse the repository at this point in the history
chore: add agent and runtime-version metadata
  • Loading branch information
cprice404 authored Aug 19, 2024
2 parents 84e4d18 + 860ef39 commit 15d2e14
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 14 deletions.
40 changes: 37 additions & 3 deletions src/lib/momento/internal/scs_control_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule Momento.Internal.ScsControlClient do

@spec list_caches(client :: t()) :: Momento.Responses.ListCaches.t()
def list_caches(client) do
metadata = %{Authorization: client.auth_token}
metadata = create_metadata(client)
list_caches_request = %Momento.Protos.ControlClient.ListCachesRequest{}

case Momento.Protos.ControlClient.ScsControl.Stub.list_caches(
Expand All @@ -60,7 +60,7 @@ defmodule Momento.Internal.ScsControlClient do

@spec create_cache(client :: t(), cache_name :: String.t()) :: Momento.Responses.CreateCache.t()
def create_cache(client, cache_name) do
metadata = %{Authorization: client.auth_token}
metadata = create_metadata(client)

create_cache_request = %Momento.Protos.ControlClient.CreateCacheRequest{
cache_name: cache_name
Expand Down Expand Up @@ -88,7 +88,7 @@ defmodule Momento.Internal.ScsControlClient do

@spec delete_cache(client :: t(), cache_name :: String.t()) :: Momento.Responses.DeleteCache.t()
def delete_cache(client, cache_name) do
metadata = %{Authorization: client.auth_token}
metadata = create_metadata(client)

delete_cache_request = %Momento.Protos.ControlClient.DeleteCacheRequest{
cache_name: cache_name
Expand All @@ -108,4 +108,38 @@ defmodule Momento.Internal.ScsControlClient do
end
end
end

@agent_data_key "__#{__MODULE__}_AGENT_DATA_SENT__"

defp should_send_agent_data? do
:erlang.get(@agent_data_key) == :undefined
end

@spec create_metadata(t()) :: %{required(String.t()) => String.t()}
defp create_metadata(client) do
base_metadata = %{
"authorization" => client.auth_token
}

if should_send_agent_data?() do
:erlang.put(@agent_data_key, true)

Map.merge(base_metadata, %{
# example agent: "elixir:cache:0.6.6"
"agent" => "elixir:cache:" <> get_library_version(),
# example runtime-version: "1.16.2"
"runtime-version" => System.version()
})
else
base_metadata
end
end

@spec get_library_version() :: String.t()
defp get_library_version do
case Application.spec(:gomomento, :vsn) do
nil -> "unknown"
version -> to_string(version)
end
end
end
59 changes: 49 additions & 10 deletions src/lib/momento/internal/scs_data_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
{:ok, ttl_milliseconds} <- get_ttl_milliseconds(ttl_seconds) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

set_request = %Momento.Protos.CacheClient.SetRequest{
cache_key: key,
Expand All @@ -75,7 +75,7 @@ defmodule Momento.Internal.ScsDataClient do
def get(data_client, cache_name, key) do
with :ok <- validate_cache_name(cache_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

get_request = %Momento.Protos.CacheClient.GetRequest{cache_key: key}

Expand Down Expand Up @@ -104,7 +104,7 @@ defmodule Momento.Internal.ScsDataClient do
def delete(data_client, cache_name, key) do
with :ok <- validate_cache_name(cache_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

delete_request = %Momento.Protos.CacheClient.DeleteRequest{cache_key: key}

Expand Down Expand Up @@ -141,7 +141,7 @@ defmodule Momento.Internal.ScsDataClient do
{:ok, ttl_milliseconds} <- get_ttl_milliseconds(collection_ttl),
{:ok, transformed_elements} <- transform_sorted_set_elements(elements) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

sorted_set_put_request = %Momento.Protos.CacheClient.SortedSetPutRequest{
set_name: sorted_set_name,
Expand Down Expand Up @@ -211,7 +211,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
:ok <- validate_sorted_set_name(sorted_set_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

start_index =
case start_rank do
Expand Down Expand Up @@ -298,7 +298,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
:ok <- validate_sorted_set_name(sorted_set_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

request_min_score =
case min_score do
Expand Down Expand Up @@ -405,7 +405,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
:ok <- validate_sorted_set_name(sorted_set_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

remove_request = %Momento.Protos.CacheClient.SortedSetRemoveRequest{
set_name: sorted_set_name,
Expand Down Expand Up @@ -449,7 +449,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
:ok <- validate_sorted_set_name(sorted_set_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

request_order =
case sort_order do
Expand Down Expand Up @@ -571,7 +571,7 @@ defmodule Momento.Internal.ScsDataClient do
with :ok <- validate_cache_name(cache_name),
:ok <- validate_sorted_set_name(sorted_set_name) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

get_scores_request = %Momento.Protos.CacheClient.SortedSetGetScoreRequest{
set_name: sorted_set_name,
Expand Down Expand Up @@ -642,7 +642,7 @@ defmodule Momento.Internal.ScsDataClient do
:ok <- validate_sorted_set_name(sorted_set_name),
{:ok, ttl_milliseconds} <- get_ttl_milliseconds(collection_ttl) do
try do
metadata = %{cache: cache_name, Authorization: data_client.auth_token}
metadata = create_metadata(cache_name, data_client)

increment_request = %Momento.Protos.CacheClient.SortedSetIncrementRequest{
set_name: sorted_set_name,
Expand Down Expand Up @@ -687,4 +687,43 @@ defmodule Momento.Internal.ScsDataClient do

defp get_ttl_milliseconds(ttl),
do: {:error, Momento.Error.invalid_argument("Unable to parse TTL from #{ttl}")}

@agent_data_key "__#{__MODULE__}_AGENT_DATA_SENT__"

defp should_send_agent_data? do
:erlang.get(@agent_data_key) == :undefined
end

@spec create_metadata(String.t(), t()) :: %{required(String.t()) => String.t()}
defp create_metadata(cache_name, data_client) do
base_metadata = %{
"cache" => cache_name,
"authorization" => data_client.auth_token
}

if should_send_agent_data?() do
:erlang.put(@agent_data_key, true)

IO.puts("Versions:")
IO.puts(get_library_version())
IO.puts(System.version())

Map.merge(base_metadata, %{
# example agent: "elixir:cache:0.6.6"
"agent" => "elixir:cache:" <> get_library_version(),
# example runtime-version: "1.16.2"
"runtime-version" => System.version()
})
else
base_metadata
end
end

@spec get_library_version() :: String.t()
defp get_library_version do
case Application.spec(:gomomento, :vsn) do
nil -> "unknown"
version -> to_string(version)
end
end
end
3 changes: 2 additions & 1 deletion src/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ defmodule Momento.MixProject do
{:google_protos, "~> 0.3"},
{:joken, "~> 2.5"},
{:jason, "~> 1.4"},
{:tls_certificate_check, "~> 1.19"}
{:tls_certificate_check, "~> 1.19"},
{:mock, "~> 0.3.8", only: :test}
]
end

Expand Down
2 changes: 2 additions & 0 deletions src/mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"protobuf": {:hex, :protobuf, "0.12.0", "58c0dfea5f929b96b5aa54ec02b7130688f09d2de5ddc521d696eec2a015b223", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "75fa6cbf262062073dd51be44dd0ab940500e18386a6c4e87d5819a58964dc45"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
Expand Down
38 changes: 38 additions & 0 deletions src/test/momento/internal/scs_control_client_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Momento.Internal.ScsControlClientTest do
use ExUnit.Case, async: false
import Mock

alias Momento.Internal.ScsControlClient
alias Momento.Protos.ControlClient.ScsControl.Stub

test "agent metadata is only sent on the first call" do
fake_channel = :fake_channel

client = %ScsControlClient{
auth_token: "test_token",
channel: fake_channel
}

with_mock Stub, [:passthrough],
create_cache: fn ^fake_channel, _request, options ->
metadata = Keyword.get(options, :metadata, %{})
send(self(), {:grpc_call, metadata})
{:ok, %{}}
end do
ScsControlClient.create_cache(client, "test_cache")
assert_received {:grpc_call, metadata}
assert Map.has_key?(metadata, "agent")
assert Map.has_key?(metadata, "runtime-version")

ScsControlClient.create_cache(client, "test_cache")
assert_received {:grpc_call, metadata}
refute Map.has_key?(metadata, "agent")
refute Map.has_key?(metadata, "runtime-version")

ScsControlClient.create_cache(client, "test_cache")
assert_received {:grpc_call, metadata}
refute Map.has_key?(metadata, "agent")
refute Map.has_key?(metadata, "runtime-version")
end
end
end
38 changes: 38 additions & 0 deletions src/test/momento/internal/scs_data_client_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Momento.Internal.ScsDataClientTest do
use ExUnit.Case, async: false
import Mock

alias Momento.Internal.ScsDataClient
alias Momento.Protos.CacheClient.Scs.Stub

test "agent metadata is only sent on the first call" do
fake_channel = :fake_channel

client = %ScsDataClient{
auth_token: "test_token",
channel: fake_channel
}

with_mock Stub, [:passthrough],
set: fn ^fake_channel, _request, options ->
metadata = Keyword.get(options, :metadata, %{})
send(self(), {:grpc_call, metadata})
{:ok, %{}}
end do
ScsDataClient.set(client, "test_cache", "key1", "value1", 60)
assert_received {:grpc_call, metadata}
assert Map.has_key?(metadata, "agent")
assert Map.has_key?(metadata, "runtime-version")

ScsDataClient.set(client, "test_cache", "key2", "value2", 60)
assert_received {:grpc_call, metadata}
refute Map.has_key?(metadata, "agent")
refute Map.has_key?(metadata, "runtime-version")

ScsDataClient.set(client, "test_cache", "key3", "value3", 60)
assert_received {:grpc_call, metadata}
refute Map.has_key?(metadata, "agent")
refute Map.has_key?(metadata, "runtime-version")
end
end
end

0 comments on commit 15d2e14

Please sign in to comment.