-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding elixir sample for request-reply (#172)
Co-authored-by: Byron Ruth <[email protected]>
- Loading branch information
1 parent
2796bea
commit 78bbf96
Showing
2 changed files
with
85 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Set up the dependencies for this script. Ordinarily you would have this set of dependencies | ||
# declared in your `mix.exs` file. | ||
Mix.install([ | ||
# For documentation on the Gnat library, see https://hexdocs.pm/gnat/readme.html | ||
{:gnat, "~> 1.7.1"}, | ||
{:jason, "~> 1.0"} | ||
]) | ||
|
||
url = System.get_env("NATS_URL", "nats://0.0.0.0:4222") | ||
uri = URI.parse(url) | ||
|
||
# Call `start_link` on `Gnat` to start the Gnat application supervisor | ||
{:ok, gnat} = Gnat.start_link(%{host: uri.host, port: uri.port}) | ||
|
||
# The `Gnat.ConnectionSupervisor` is a process that monitors your NATS connection. If connection | ||
# is lost, this process will retry according to its backoff settings to re-establish a connection. | ||
# You can communicate with NATS without this, but we recommend using supervised connections | ||
# and consumers | ||
gnat_supervisor_settings = %{ | ||
name: :gnat, | ||
backoff_period: 4_000, | ||
connection_settings: [ | ||
%{host: uri.host, port: uri.port} | ||
] | ||
} | ||
|
||
{:ok, _conn} = Gnat.ConnectionSupervisor.start_link(gnat_supervisor_settings) | ||
|
||
# Give the connection time to establish (this is only needed for these examples and not in production) | ||
if Process.whereis(:gnat) == nil do | ||
Process.sleep(300) | ||
end | ||
|
||
|
||
# Now let's set up a consumer supervisor. We use the `subscription_topics` field in the configuration | ||
# map to set up a list of subscriptions which can optionally have queue names. | ||
consumer_supervisor_settings = %{ | ||
connection_name: :gnat, | ||
# This is the name of a module defined below | ||
module: ExampleService, | ||
subscription_topics: [ | ||
%{topic: "request.demo"}, | ||
] | ||
|
||
} | ||
|
||
# Starting the consumer supervisor will create the subscription and will monitor | ||
# the connection to re-establish subscriptions in case of failure | ||
{:ok , _pid} = Gnat.ConsumerSupervisor.start_link(consumer_supervisor_settings) | ||
|
||
|
||
# This is a module that conforms to the `Gnat.Server` behavior. The name of this module | ||
# matches the `module` field in the consumer supervisor settings. | ||
defmodule ExampleService do | ||
use Gnat.Server | ||
|
||
# This handler will simulate an error | ||
def request(%{topic: "request.demo", body: body}) when body == "failure" do | ||
{:error, "something went wrong!"} | ||
end | ||
|
||
# This handler is matching just on the subject | ||
def request(%{topic: "request.demo", body: body}) do | ||
IO.puts "Demo request received message: #{inspect(body)}" | ||
{:reply, "This is a demo"} | ||
end | ||
|
||
# Defining an error handler is optional, the default one will just call Logger.error for you | ||
def error(%{gnat: gnat, reply_to: reply_to}, error) do | ||
Gnat.pub(gnat, reply_to, "An error occurred: #{inspect(error)}") | ||
end | ||
end | ||
|
||
# Now that we know there's an active subscription on the `request.demo` subject, we can | ||
# make a request and process the reply using `Gnat.request` | ||
{:ok, %{body: res}} = Gnat.request(:gnat, "request.demo", "input data") | ||
IO.puts("First result: #{res}") | ||
|
||
{:ok, %{body: res}} = Gnat.request(:gnat, "request.demo", "more data") | ||
IO.puts("Second result: #{res}") | ||
|
||
# Now cause a failure so we can see error responses | ||
{:ok, %{body: res}} = Gnat.request(:gnat, "request.demo", "failure") | ||
IO.puts("Failure result: #{res}") |
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