Packages
forge_sdk
0.26.0
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.7
1.0.6
1.0.4
1.0.4-p1
1.0.4-p0
1.0.3
1.0.2
1.0.2-p1
1.0.1
1.0.1-p1
1.0.0
0.40.6
0.40.5
0.40.4
0.40.3
0.40.2
0.40.1
0.40.0
0.39.1
0.39.0
0.38.6
0.38.5
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.5
0.37.4
0.37.3
0.37.2
0.37.1
0.37.0
0.34.0
0.33.2
0.33.1
0.33.0
0.32.2
0.32.1
0.32.0
0.31.1
0.31.0
0.30.0
0.29.1
0.29.0
0.28.3
0.28.2
0.28.1
0.28.0
0.27.4
0.27.3
0.27.2
0.27.1
0.27.0
0.26.6
0.26.5
0.26.4
0.26.3
0.26.1
0.26.0
Elixir / Erlang version of the SDK for Forge framework.
Current section
Files
Jump to
Current section
Files
lib/forge_sdk/rpc/conn.ex
defmodule ForgeSdk.Rpc.Conn do
@moduledoc """
Persistent gRPC connection to Forge GRPC server.
"""
use Connection
require Logger
alias GRPC.Stub, as: Client
def start_link(addr, opts) do
Connection.start_link(__MODULE__, {addr, opts}, name: __MODULE__)
end
def get_chan do
case Process.whereis(ForgeSdk.Rpc.Conn) do
nil -> nil
_ -> Connection.call(__MODULE__, :get_chan)
end
end
@spec close :: any()
def close, do: Connection.call(__MODULE__, :close)
def child_spec(addr) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [addr, []]},
type: :worker,
restart: :permanent,
shutdown: 500
}
end
# callbacks
def init({"unix://" <> addr, opts}),
do: {:connect, :init, %{addr: addr, opts: opts, chan: nil}}
def init({"tcp://" <> addr, opts}), do: {:connect, :init, %{addr: addr, opts: opts, chan: nil}}
def connect(_, %{chan: nil, addr: addr, opts: opts} = state) do
Logger.info("Forge ABI RPC: reconnect to #{addr}")
case Client.connect(addr, opts) do
{:ok, chan} -> {:ok, %{state | chan: chan}}
{:error, _} -> {:backoff, 500, state}
end
end
def disconnect(info, %{chan: chan} = state) do
{:ok, _} = Client.disconnect(chan)
case info do
{:close, from} -> Connection.reply(from, :ok)
{:error, :closed} -> Logger.error("Forge SDK RPC connection closed")
{:error, reason} -> Logger.error("Forge SDK RPC connection error: #{inspect(reason)}")
end
{:connect, :reconnect, %{state | chan: nil}}
end
# callbacks
def handle_call(_, _, %{chan: nil} = state) do
{:reply, {:error, :closed}, state}
end
def handle_call(:get_chan, _from, %{chan: chan} = state) do
{:reply, chan, state}
end
def handle_call(:close, from, state) do
{:disconnect, {:close, from}, state}
end
end