ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - ephe-meral/ex_sider: Elixir <-> Redis datastructure adapter
Elixir <-> Redis datastructure adapter. Contribute to ephe-meral/ex_sider development by creating an account on GitHub.
Visit Site

GitHub - ephe-meral/ex_sider: Elixir <-> Redis datastructure adapter

GitHub - ephe-meral/ex_sider: Elixir <-> Redis datastructure adapter

Build Status Hex.pm Hex version Documentation

ex_sider

Elixir <-> Redis datastructure adapter

setup

In your mix.exs file:

def deps do
  [{:ex_sider, "~> 0.1"},
   # the following is only needed if using a Redix pool:
   {:poolboy, "~> 1.5"},
   {:redix, ">= 0.0.0"}]
end

In your config file:

config ex_sider,
  redis_adapter: MyApp.RedixPool # currently the only supported adapter, see below

# also make sure to configure the redis adapter correctly

use case: redis interface

This can be used (potentially, if necessary) with different Redis adapters, but for now I'll stick with Redix. From the example we can create a new RedixPool e.g. like so:

# Copied from github.com/whatyouhide/redix README.md
defmodule MyApp.RedixPool do
  use Supervisor

  @redis_connection_params host: "localhost", password: ""

  def start_link do
    Supervisor.start_link(__MODULE__, [])
  end

  def init([]) do
    pool_opts = [
      name: {:local, :redix_poolboy},
      worker_module: Redix,
      size: 10,
      max_overflow: 5,
    ]

    children = [
      :poolboy.child_spec(:redix_poolboy, pool_opts, @redis_connection_params)
    ]

    supervise(children, strategy: :one_for_one, name: __MODULE__)
  end

  def command(command) do
    :poolboy.transaction(:redix_poolboy, &Redix.command(&1, command))
  end

  def pipeline(commands) do
    :poolboy.transaction(:redix_poolboy, &Redix.pipeline(&1, commands))
  end
end

We now update our ex_sider config with the correct module name (see above), and also make sure that the RedixPool is started when we start our Application:

defmodule MyApp do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      # ...
      supervisor(MyApp.RedixPool, [[]]),
      # ...
    ]

    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Finally, after this setup, we can use the ex_redis modules like any normal Map, Set or List, e.g.: (Actually, take this with a grain of salt: Since this is an ongoing effort, interfaces might be incomplete - but please request specific improvements or contribute!)

redis_set = RedisSet.new("my-set-name")

# by default, ex_sider uses a 'binary' mode, where it pipes all
# terms given to it into :erlang.term_to_binary/1, and all terms
# that it retrieves through :erlang.binary_to_term/1
data = ["surprisingly", :we_can_store, "all kinds of data!!!", 1, 1, 1]

# we can use for comprehensions:
for x <- data, into: redis_set, do: x

# and any kind of Enum operation, e.g.:
Enum.to_list(redis_set)
# => ["surprisingly", :we_can_store, "all kinds of data!!!", 1]
# note the missing 1's because we are using a RedisSet

use case directly dump data into a redis hash

Note that this functionality might be made more implicit in the future by implementing the Access, Enumerable and Collectable functionality

redis_hash = RedisHash.new("my-hash-name") # initializes the redishash with the korrekt key
RedisHash.push(redis_hash, %{"some_value" => 123, "abc" => :abc}) # note: keys must be binaries!
# => :ok
RedisHash.pull(redis_hash)
# => %{"some_value" => 123, "abc" => :abc}

use case: simple local & redis cache

Essentially, this is a RedisHash under the hood, but caches data and changes locally. It can be used to remotely cache elixir maps with simple push/pull sync semantics and no strategy for conflict resolution. The use case for this is to store (also Erlang-Node independant) the state of a process that will only ever be existing once in the cluster, but might be restarted often.

redis_cache = RedisCache.new("my-hash-name") # pulls the existing state from the repo automatically if any
redis_cache = RedisCache.merge(redis_cache, %{"some" => :values, "that_i_want" => "to store"}) # does a local caching
RedisCache.unpushed_changes?(redis_cache)
# => true

redis_cache = RedisCache.push(redis_cache) # pushes the local changes

RedisCache.unpushed_changes?(redis_cache)
# => false

remarks

Mutability - All datastructures implemented here are mutable, that means, that every operation that changes any part of them (i.e. writes data) will change for all parts of the application that have a reference to this datastructure. This is because we actually only implement a thin adapter layer based on Elixir Protocols, that interface with redis in order to store data.

Binary Data - Any data will, by default, be stored as an erlang term that is being converted to binary beforehand. That means that - in case you access Redis without ex_sider - that you will have to call :erlang.binary_to_term on anything that you retrieve from it. If that is not an option for you, simply disable binary mode when initialising the datastructure:

# to disable binary mode (only values that are binaries can be used then, like e.g. elixir strings)
redis_set = RedisSet.new("my-set-name", binary_mode: false)

This Project - This project is supposed to be a helper to make interfacing with Redis simpler. It is by no means: complete, perfectly documented or otherwise done. Any help is appreciated, just fork & PR, create issues etc. Business as usual.

is it any good?

bien sûr.

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory