Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supported Setting for Cache Adapter #262

Merged
merged 2 commits into from
Aug 6, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 73 additions & 10 deletions lib/open_api_spex/plug/cache.ex
Original file line number Diff line number Diff line change
@@ -1,50 +1,113 @@
defmodule OpenApiSpex.Plug.Cache do
@moduledoc false
@moduledoc """
Cache for OpenApiSpex

@callback get(module) :: {OpenApiSpex.OpenApi.t(), map} | nil
@callback put(module, {OpenApiSpex.OpenApi.t(), map}) :: :ok
Settings:

@spec adapter() :: OpenApiSpex.Plug.AppEnvCache | OpenApiSpex.Plug.PersistentTermCache
def adapter do
if function_exported?(:persistent_term, :info, 0) do
```elixir
config :open_api_spex, :cache_adapter Module
```

There are already had three cache adapter:
* `OpenApiSpex.Plug.PersistentTermCache` - default
* `OpenApiSpex.Plug.AppEnvCache` - if VM not supported `persistent_term`
mbuhot marked this conversation as resolved.
Show resolved Hide resolved
* `OpenApiSpex.Plug.NoneCache` - none cache

If you are constantly modifying specs during development, you can setting
like this in `dev.exs`:

```elixir
config :open_api_spex, :cache_adapter OpenApiSpex.Plug.NoneCache
mbuhot marked this conversation as resolved.
Show resolved Hide resolved
```
"""

default_adapter =
if(function_exported?(:persistent_term, :info, 0)) do
OpenApiSpex.Plug.PersistentTermCache
else
OpenApiSpex.Plug.AppEnvCache
end

@default_adapter default_adapter

@callback get(module) :: {OpenApiSpex.OpenApi.t(), map} | nil
@callback put(module, {OpenApiSpex.OpenApi.t(), map}) :: :ok
@callback erase(module) :: :ok

@doc """
Get cache adapter
"""
@spec adapter() :: module()
def adapter do
Application.get_env(:open_api_spex, :cache_adapter, @default_adapter)
end

@doc """
Only erase cache, put again when plug starting
"""
@spec refresh() :: :ok
def refresh do
adapter = adapter()
adapter.erase()
end
end

defmodule OpenApiSpex.Plug.AppEnvCache do
@moduledoc false
@behaviour OpenApiSpex.Plug.Cache

@impl OpenApiSpex.Plug.Cache
@impl true
def get(spec_module) do
Application.get_env(:open_api_spex, spec_module)
end

@impl OpenApiSpex.Plug.Cache
@impl true
def put(spec_module, spec) do
:ok = Application.put_env(:open_api_spex, spec_module, spec)
end

@impl true
def erase(spec_module) do
Application.delete_env(:open_api_spex, spec_module)
end
end

if function_exported?(:persistent_term, :info, 0) do
defmodule OpenApiSpex.Plug.PersistentTermCache do
@moduledoc false
@behaviour OpenApiSpex.Plug.Cache

@impl OpenApiSpex.Plug.Cache
@impl true
def get(spec_module) do
:persistent_term.get(spec_module)
rescue
ArgumentError ->
nil
end

@impl OpenApiSpex.Plug.Cache
@impl true
def put(spec_module, spec) do
:ok = :persistent_term.put(spec_module, spec)
end

@impl true
def erase(spec_module) do
:persistent_term.erase(spec_module)
:ok
end
end
end

defmodule OpenApiSpex.Plug.NoneCache do
@moduledoc false
@behaviour OpenApiSpex.Plug.Cache

@impl true
def get(_spec_module), do: nil

@impl true
def put(_spec_module, _spec), do: :ok

@impl true
def erase(_spec_module), do: :ok
end