{"id":13508832,"url":"https://github.com/ephe-meral/ex_sider","last_synced_at":"2026-02-23T05:01:42.151Z","repository":{"id":62429446,"uuid":"58392539","full_name":"ephe-meral/ex_sider","owner":"ephe-meral","description":"Elixir \u003c-\u003e Redis datastructure adapter","archived":false,"fork":false,"pushed_at":"2016-09-02T15:08:05.000Z","size":23,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-19T04:24:41.081Z","etag":null,"topics":["elixir","redis","wip"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ephe-meral.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-09T16:44:03.000Z","updated_at":"2020-04-25T11:55:48.000Z","dependencies_parsed_at":"2022-11-01T20:07:28.705Z","dependency_job_id":null,"html_url":"https://github.com/ephe-meral/ex_sider","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ephe-meral/ex_sider","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ephe-meral%2Fex_sider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ephe-meral%2Fex_sider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ephe-meral%2Fex_sider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ephe-meral%2Fex_sider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ephe-meral","download_url":"https://codeload.github.com/ephe-meral/ex_sider/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ephe-meral%2Fex_sider/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29738083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T04:51:08.365Z","status":"ssl_error","status_checked_at":"2026-02-23T04:49:15.865Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","redis","wip"],"created_at":"2024-08-01T02:00:59.156Z","updated_at":"2026-02-23T05:01:42.108Z","avatar_url":"https://github.com/ephe-meral.png","language":"Elixir","funding_links":[],"categories":["ORM and Datamapping"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/ephe-meral/ex_sider.svg?branch=master)](https://travis-ci.org/ephe-meral/ex_sider)\n[![Hex.pm](https://img.shields.io/hexpm/l/ex_sider.svg \"WTFPL Licensed\")](https://github.com/ephe-meral/ex_sider/blob/master/LICENSE)\n[![Hex version](https://img.shields.io/hexpm/v/ex_sider.svg \"Hex version\")](https://hex.pm/packages/ex_sider)\n[![Documentation](https://img.shields.io/badge/docs-hexpm-blue.svg)](http://hexdocs.pm/ex_sider/)\n\n\n# ex_sider\n\nElixir \u0026lt;-\u003e Redis datastructure adapter\n\n## setup\n\nIn your `mix.exs` file:\n\n```elixir\ndef deps do\n  [{:ex_sider, \"~\u003e 0.1\"},\n   # the following is only needed if using a Redix pool:\n   {:poolboy, \"~\u003e 1.5\"},\n   {:redix, \"\u003e= 0.0.0\"}]\nend\n```\n\nIn your config file:\n\n```elixir\nconfig ex_sider,\n  redis_adapter: MyApp.RedixPool # currently the only supported adapter, see below\n\n# also make sure to configure the redis adapter correctly\n```\n\n## use case: redis interface\n\nThis can be used (potentially, if necessary) with different Redis adapters, but for\nnow I'll stick with [Redix](https://github.com/whatyouhide/redix). From the example\nwe can create a new RedixPool e.g. like so:\n\n```elixir\n# Copied from github.com/whatyouhide/redix README.md\ndefmodule MyApp.RedixPool do\n  use Supervisor\n\n  @redis_connection_params host: \"localhost\", password: \"\"\n\n  def start_link do\n    Supervisor.start_link(__MODULE__, [])\n  end\n\n  def init([]) do\n    pool_opts = [\n      name: {:local, :redix_poolboy},\n      worker_module: Redix,\n      size: 10,\n      max_overflow: 5,\n    ]\n\n    children = [\n      :poolboy.child_spec(:redix_poolboy, pool_opts, @redis_connection_params)\n    ]\n\n    supervise(children, strategy: :one_for_one, name: __MODULE__)\n  end\n\n  def command(command) do\n    :poolboy.transaction(:redix_poolboy, \u0026Redix.command(\u00261, command))\n  end\n\n  def pipeline(commands) do\n    :poolboy.transaction(:redix_poolboy, \u0026Redix.pipeline(\u00261, commands))\n  end\nend\n```\n\nWe 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:\n\n```elixir\ndefmodule MyApp do\n  use Application\n\n  def start(_type, _args) do\n    import Supervisor.Spec, warn: false\n\n    children = [\n      # ...\n      supervisor(MyApp.RedixPool, [[]]),\n      # ...\n    ]\n\n    opts = [strategy: :one_for_one, name: MyApp.Supervisor]\n    Supervisor.start_link(children, opts)\n  end\nend\n```\n\nFinally, after this setup, we can use the `ex_redis` modules like any normal Map, Set or List, e.g.:\n(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!)\n\n```elixir\nredis_set = RedisSet.new(\"my-set-name\")\n\n# by default, ex_sider uses a 'binary' mode, where it pipes all\n# terms given to it into :erlang.term_to_binary/1, and all terms\n# that it retrieves through :erlang.binary_to_term/1\ndata = [\"surprisingly\", :we_can_store, \"all kinds of data!!!\", 1, 1, 1]\n\n# we can use for comprehensions:\nfor x \u003c- data, into: redis_set, do: x\n\n# and any kind of Enum operation, e.g.:\nEnum.to_list(redis_set)\n# =\u003e [\"surprisingly\", :we_can_store, \"all kinds of data!!!\", 1]\n# note the missing 1's because we are using a RedisSet\n```\n\n## use case directly dump data into a redis hash\n\n_Note that this functionality might be made more implicit in the future by implementing the Access, Enumerable and Collectable functionality_\n\n```elixir\nredis_hash = RedisHash.new(\"my-hash-name\") # initializes the redishash with the korrekt key\nRedisHash.push(redis_hash, %{\"some_value\" =\u003e 123, \"abc\" =\u003e :abc}) # note: keys must be binaries!\n# =\u003e :ok\nRedisHash.pull(redis_hash)\n# =\u003e %{\"some_value\" =\u003e 123, \"abc\" =\u003e :abc}\n```\n\n## use case: simple local \u0026 redis cache\n\nEssentially, this is a RedisHash under the hood, but caches data and changes locally.\nIt can be used to remotely cache elixir maps with simple push/pull sync semantics and no strategy for conflict resolution.\nThe 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.\n\n```elixir\nredis_cache = RedisCache.new(\"my-hash-name\") # pulls the existing state from the repo automatically if any\nredis_cache = RedisCache.merge(redis_cache, %{\"some\" =\u003e :values, \"that_i_want\" =\u003e \"to store\"}) # does a local caching\nRedisCache.unpushed_changes?(redis_cache)\n# =\u003e true\n\nredis_cache = RedisCache.push(redis_cache) # pushes the local changes\n\nRedisCache.unpushed_changes?(redis_cache)\n# =\u003e false\n```\n\n## remarks\n\n**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.\n\n**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:\n\n```elixir\n# to disable binary mode (only values that are binaries can be used then, like e.g. elixir strings)\nredis_set = RedisSet.new(\"my-set-name\", binary_mode: false)\n```\n\n**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 \u0026 PR, create issues etc. Business as usual.\n\n## is it any good?\n\nbien sûr.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fephe-meral%2Fex_sider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fephe-meral%2Fex_sider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fephe-meral%2Fex_sider/lists"}