Skip to content

Commit

Permalink
chore: refactor so that Task async/await is handled outside of the API
Browse files Browse the repository at this point in the history
This gives us slightly better typing on the API methods and allows callers
to choose whether to launch async or not.
  • Loading branch information
cprice404 committed Jun 8, 2023
1 parent 31713a4 commit 33bb7b8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 27 deletions.
39 changes: 29 additions & 10 deletions examples/basic.exs
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
defmodule Momento.Examples.Basic do
@spec generate_key(integer) :: String.t
@spec generate_key(integer) :: String.t()
def generate_key(i) do
"key#{i}"
end

@spec execute_set(Momento.CacheClient.t, String.t) :: String.t
def execute_set(cache_client, key) do
@spec issue_set(Momento.CacheClient.t(), String.t()) :: {String.t(), Task.t()}
def issue_set(cache_client, key) do
IO.puts("Executing a 'set' for key: #{key}")
response = Task.await(Momento.CacheClient.set(cache_client, key, "foo", 42))
{key, Task.async(fn -> Momento.CacheClient.set(cache_client, key, "foo", 42) end)}
end

@spec await_set({String.t(), Task.t()}) :: String.t()
def await_set({key, set_task}) do
response = Task.await(set_task)
case response do
:success -> IO.puts("'set' successful for key #{key}")
{:error, error} -> IO.puts("Got an error for key #{key}: #{inspect(error)}")
end
key
end

@spec execute_get(Momento.CacheClient.t, String.t) :: String.t
def execute_get(cache_client, key) do
@spec issue_get(Momento.CacheClient.t(), String.t()) :: {String.t(), Task.t()}
def issue_get(cache_client, key) do
IO.puts("Executing a 'get' for key: #{key}")
response = Task.await(Momento.CacheClient.get(cache_client, key))
{key, Task.async(fn -> Momento.CacheClient.get(cache_client, key) end)}
end

@spec await_get({String.t(), Task.t()}) :: String.t()
def await_get({key, get_task}) do
response = Task.await(get_task)
case response do
:hit -> IO.puts("'get' resulted in a 'hit' for key #{key}: #{inspect(response)}")
:miss -> IO.puts("'get' resulted in a 'miss' for key #{key}.")
Expand All @@ -34,8 +44,17 @@ config = %Momento.Configuration{}
cache_client = %Momento.CacheClient{config: config}


1..20
set_tasks = 1..20
|> Stream.map(&Momento.Examples.Basic.generate_key(&1))
|> Stream.map(&Momento.Examples.Basic.execute_set(cache_client, &1))
|> Stream.map(&Momento.Examples.Basic.execute_get(cache_client, &1))
|> Stream.map(&Momento.Examples.Basic.issue_set(cache_client, &1))
|> Enum.to_list

get_tasks = set_tasks
|> Stream.map(&Momento.Examples.Basic.await_set(&1))
|> Stream.map(&Momento.Examples.Basic.issue_get(cache_client, &1))
|> Enum.to_list

# force the completion of the tasks
get_tasks
|> Stream.map(&Momento.Examples.Basic.await_get(&1))
|> Enum.to_list
36 changes: 19 additions & 17 deletions src/lib/momento/cache_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ defmodule Momento.CacheClient do
TODO
"""
@spec set(String.t(), binary, binary, float) :: Task.t()
@spec set(String.t(), binary, binary, float) :: Momento.Responses.Set.t()
def set(cache_name, key, value, ttl_seconds) do
Task.async(fn ->
rand = :rand.uniform(2)
case rand do
1 -> :success
2 -> {:error, %{}}
end
end)
time_to_sleep = :rand.uniform(100)
:timer.sleep(time_to_sleep)
IO.puts("Completed 'set' for key #{key}")
rand = :rand.uniform(2)
case rand do
1 -> :success
2 -> {:error, %{}}
end
end


Expand All @@ -35,15 +36,16 @@ defmodule Momento.CacheClient do
TODO
"""
@spec get(String.t(), binary) :: Task.t()
@spec get(String.t(), binary) :: Momento.Responses.Get.t()
def get(cache_name, key) do
Task.async(fn ->
rand = :rand.uniform(3)
case rand do
1 -> :hit
2 -> :miss
3 -> {:error, %{}}
end
end)
time_to_sleep = :rand.uniform(100)
:timer.sleep(time_to_sleep)
IO.puts("Completed 'get' for key #{key}")
rand = :rand.uniform(3)
case rand do
1 -> :hit
2 -> :miss
3 -> {:error, %{}}
end
end
end

0 comments on commit 33bb7b8

Please sign in to comment.