Ecto: Example with multiple read slaves

Created on 27 Feb 2015  路  5Comments  路  Source: elixir-ecto/ecto

Low priority just want an example with multiple read slaves. Django has issues with it, so my company uses HAproxy to maintain a pool of read slaves. With this I want to make sure ecto does that and then have an example of how to do it right. Let me know if you need more info!

Most helpful comment

You just define multiple repositories: MyApp.Repo, MyApp.Repo.Read1, MyApp.Repo.Read2, up to N. Their configuration is going to be similar and you can easily share them in the config/config.exs file.

Now, every time you need to do a read, you just need to do:

def repo do
  at = :erlang.phash2({self(), :erlang.system_time(), :erlang.unique_integer()}, n)
  Enum.fetch! [MyApp.Repo.Read1, ..., ], at
end

where n is the number of repos.

Alternatively you can create a facade repository that does exactly that:

defmodule Sample.Repo do
  def all(query, options \\ []) do
    read_repos.all(query, options) # Read goes through the random above
  end

  def update(changes, options \\ []) do
    Sample.Repo.Master.update(changes, options) # Those go to master
  end
end

So we don't have something out of the box but, because the repository operations are explicit, it is very easy to cache or add read/write setup.

All 5 comments

You just define multiple repositories: MyApp.Repo, MyApp.Repo.Read1, MyApp.Repo.Read2, up to N. Their configuration is going to be similar and you can easily share them in the config/config.exs file.

Now, every time you need to do a read, you just need to do:

def repo do
  at = :erlang.phash2({self(), :erlang.system_time(), :erlang.unique_integer()}, n)
  Enum.fetch! [MyApp.Repo.Read1, ..., ], at
end

where n is the number of repos.

Alternatively you can create a facade repository that does exactly that:

defmodule Sample.Repo do
  def all(query, options \\ []) do
    read_repos.all(query, options) # Read goes through the random above
  end

  def update(changes, options \\ []) do
    Sample.Repo.Master.update(changes, options) # Those go to master
  end
end

So we don't have something out of the box but, because the repository operations are explicit, it is very easy to cache or add read/write setup.

If this technique works for you, it would be awesome if you could write a blog post about it. I think it would help tons of people!

Jose that should, and it's quote obvious I don't know why I didn't think of it. I'll def work on writing something up!

@mcginleyr1 it is definitely a neat idea, I didn't think about it though, credit goes to @mschae!

I just published a simple package for multiple read slave.
https://github.com/kenta-aktsk/read_repos

Thanks for information of this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jbence picture jbence  路  3Comments

brandonparsons picture brandonparsons  路  3Comments

ZhengQingchen picture ZhengQingchen  路  4Comments

alaadahmed picture alaadahmed  路  4Comments

atsheehan picture atsheehan  路  4Comments