试着将 Ecto Model 缓存在 Memcached 等地方

缓存Ecto Model

在这里我们将使用 memcache_client。

例如,有这样的User模型

defmodule Models.User do
  use Web, :model

  schema "users" do
    field :username, :string
    field :email, :string

    timestamps
  end

  @required_fields ~w(username email)
  @optional_fields ~w()

  @doc """
  Creates a changeset based on the `model` and `params`.
  If no params are provided, an invalid changeset is returned
  with no validation performed.
  """
  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

我试着把用户直接加进来。

iex(1)> user = %Models.User{}
%Models.User{__meta__: #Ecto.Schema.Metadata<:built>, username: nil, email: nil, inserted_at: nil, updated_at: nil}

iex(2)> Memcache.Client.set("key", user)
** (ArgumentError) argument error
    (memcache_client) lib/memcache_client.ex:253: Memcache.Client.store_request/4
    (memcache_client) lib/memcache_client.ex:242: Memcache.Client.do_store/4

直接输入可能会导致错误发生。

将其转换为二进制并进行设置

iex(3)> data = :erlang.term_to_binary(user)
<<131, 116, 0, 0, 0, 17, 100, 0, 8, 95, 95, 109, 101, 116, 97, 95, 95, 116, 0,
  0, 0, 4, 100, 0, 10, 95, 95, 115, 116, 114, 117, 99, 116, 95, 95, 100, 0, 27,
  69, 108, 105, 120, 105, 114, 46, 69, 99, 116, 111, 46, ...>>

iex(4)> Memcache.Client.set("key", data)
%Memcache.Client.Response{cas: 1, data_type: nil, extras: "", key: "",
 status: :ok, value: ""}

在获取时,将从二进制转换为 Ecto Model。

iex(5)> response = Memcache.Client.get("key")
%Memcache.Client.Response{cas: 1, data_type: 0, extras: <<0, 0, 0, 0>>, key: "",
 status: :ok,
 value: <<131, 116, 0, 0, 0, 17, 100, 0, 8, 95, 95, 109, 101, 116, 97, 95, 95,
   116, 0, 0, 0, 4, 100, 0, 10, 95, 95, 115, 116, 114, 117, 99, 116, 95, 95,
   100, 0, 27, 69, 108, 105, 120, 105, 114, 46, ...>>}

iex(6)> user = :erlang.binary_to_term(response.value)
%Models.User{__meta__: #Ecto.Schema.Metadata<:built>, username: nil, email: nil, inserted_at: nil, updated_at: nil}

如果将其转换为二进制,无论是Map还是Struct,都可以将其设置到memcache或redis中。

广告
将在 10 秒后关闭
bannerAds