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

Adapter configuration per-env? #171

Closed
tpitale opened this issue Oct 12, 2022 · 2 comments
Closed

Adapter configuration per-env? #171

tpitale opened this issue Oct 12, 2022 · 2 comments

Comments

@tpitale
Copy link

tpitale commented Oct 12, 2022

Is it, or would it be, possible to configure the adapter based on the environment? E.g., dev uses a local cache, but released environments use the redis adapter.

@cabol
Copy link
Owner

cabol commented Oct 15, 2022

Hey! I think this issue #155 is related to this, there is an example of how to do it, but let me put it here and maybe also another alternative.

You can add a configuration parameter at the app level to define the adapter to use, for example:

adapter = Application.get_env(:my_app, :cache_adapter, Nebulex.Adapters.Local)

defmodule MyApp.Cache do
  otp_app: :my_app,
  adapter: adapter
end

And then you can use the different config files depending on the environment, for example in the prod.exs or runtime.exs you could configure:

config :my_app, cache_adapter: NebulexRedisAdapter

This option as you can see works in compilation time, but you can also write something to do it in runtime. For example, define the two caches, the one using Redis adapter and another one for test purposes let's say, like:

defmodule MyApp.Cache do
  defmodule RedisCache do
    use Nebulex.Cache,
      otp_app: :my_app,
      adapter: NebulexRedisAdapter
  end

  defmodule LocalCache do
    use Nebulex.Cache,
      otp_app: :my_app,
      adapter: Nebulex.Adapters.Local
  end

  # Function to get the cache to use in runtime
  def cache do
    Application.get_env(:my_app, :cache, MyApp.Cache.LocalCache)
  end
end

It uses Application.get_env/3 to get the cache, but you could also use the :persistent_term to store the cache too, like:

def cache do
  if cache = :persistent_term.get({__MODULE__, :cache}, nil) do
    cache
  else
    # Retrieve it from the application config
    cache = Application.get_env(:my_app, :cache, MyApp.Cache.LocalCache)

    # Cache it into the persistent_term
    :ok = :persistent_term.put({__MODULE__, :cache}, cache)

    cache
  end
end

Then, when using the cache, you have to call it like so:

MyApp.Cache.cache().put("foo", "bar")

MyApp.Cache.cache().get("foo")

And, in your application module:

def start(_type, _args) do
  children = [
    MyApp.Cache.cache()
  ]

  ...
end

And remember to configure it in your config files, for example in your runtime.exs:

import Config

if config_env == :prod do
  config :my_app, cache: NebulexRedisAdapter

  ...
end

Those are workarounds that I've used, but for version 3.0 I will think if there is a better way to handle it, in the meantime I hope that helps, let me know, and stay tuned! Thanks!

@tpitale tpitale closed this as completed Oct 15, 2022
@tpitale
Copy link
Author

tpitale commented Oct 15, 2022

Thanks @cabol!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants