Created
April 25, 2016 02:32
-
-
Save todd/105519c57ef176336e135fa1ad4e4e6c to your computer and use it in GitHub Desktop.
Redis Keyevents -> RabbitMQ Messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# mix.exs | |
defmodule RedisRabbitElixir.Mixfile do | |
use Mix.Project | |
def project do | |
[app: :redis_rabbit_elixir, | |
version: "0.0.1", | |
elixir: "~> 1.2", | |
build_embedded: Mix.env == :prod, | |
start_permanent: Mix.env == :prod, | |
deps: deps] | |
end | |
# Configuration for the OTP application | |
# | |
# Type "mix help compile.app" for more information | |
def application do | |
[applications: [:logger, :amqp, :redix]] | |
end | |
# Dependencies can be Hex packages: | |
# | |
# {:mydep, "~> 0.3.0"} | |
# | |
# Or git/path repositories: | |
# | |
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} | |
# | |
# Type "mix help deps" for more examples and options | |
defp deps do | |
[ | |
{:amqp, "~> 0.1.4"}, | |
{:redix, "~> 0.3.6"} | |
] | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/redis_rabbit_elixir.ex | |
# Demo implementation of an Elixir GenServer that will subscribe to Redis | |
# Key events and forward the affected key name to RabbitMQ. | |
# | |
# Run instructions: | |
# | |
# Install Rabbitmq, Redis, and Elixir on your machine. This demo assumes | |
# Rabbit and Redis are running on the default ports on localhost. | |
# | |
# From the project root, run `iex -S mix` to start the Elixir REPL with this | |
# code compiled. Start the server by invoking: | |
# | |
# {:ok, pid} = RedisRabbitElixir.start_link | |
# | |
# The GenServer is now running and pattern subscribed to our Redis instance. | |
# | |
# To send some sample events, enable keyevent notifications in Redis: | |
# | |
# $ redis-cli | |
# 127.0.0.1:6379> CONFIG SET notify-keyspace-events AE | |
# OK | |
# 127.0.0.1:6379> SET foo bar | |
# OK | |
# | |
# You see the following output in your iex session: | |
# | |
# Received PubSub message: foo | |
# | |
# And you should see the message in our Rabbit queue: | |
# | |
# $ sudo rabbitmqctl list_queues | |
# Listing queues ... | |
# rabbit_channel_foo 1 | |
defmodule RedisRabbitElixir do | |
use GenServer | |
def start_link do | |
GenServer.start_link(__MODULE__, :ok, name: :redis_pubsub_test) | |
end | |
def init(:ok) do | |
{:ok, %{pub_sub_conn: nil}, 0} | |
end | |
def handle_info(:timeout, _state) do | |
{:ok, client_sub} = Redix.PubSub.start_link | |
# Registering `self()` as the recipient will send published messages | |
# to the GenServer to be handled by `handle_info` for :message. | |
:ok = Redix.PubSub.psubscribe(client_sub, "__keyevent@*__:set", self()) | |
{:noreply, %{pub_sub_conn: client_sub}} | |
end | |
def handle_info({:redix_pubsub, :psubscribe, _channel, _}, state) do | |
{:noreply, state} | |
end | |
def handle_info({:redix_pubsub, :pmessage, message, _channel}, state) do | |
IO.puts "Received PubSub message: #{message}" | |
send_key_to_rabbit(message) | |
{:noreply, state} | |
end | |
defp send_key_to_rabbit(key) do | |
# Spawns a new Elixir Process (not a system one) to send the key to Rabbit. | |
# The process will exit automatically once its work is done. | |
# This can probably be refactored into a different GenServer module to store | |
# connection state if we don't want to constantly be opening and closing | |
# connections to Rabbit. | |
spawn fn -> | |
{:ok, connection} = AMQP.Connection.open | |
{:ok, channel} = AMQP.Channel.open(connection) | |
AMQP.Queue.declare(channel, "rabbit_channel_foo") | |
AMQP.Basic.publish(channel, "", "rabbit_channel_foo", key) | |
AMQP.Connection.close(connection) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment