defmodule GRPC.Server.Supervisor do use Supervisor @moduledoc """ A simple supervisor to start your servers. You can add it to your OTP tree as below. But to make the servers start, you have to config `grpc` defmodule Your.App do use Application def start(_type, _args) do import Supervisor.Spec children = [ supervisor(GRPC.Server.Supervisor, [{Your.Endpoint, 50051(, opts)}]) ] opts = [strategy: :one_for_one, name: __MODULE__] Supervisor.start_link(children, opts) end end # config.exs config :grpc, start_server: true or run `mix grpc.server` on local View `child_spec/3` for opts. """ @default_adapter GRPC.Adapter.Cowboy require Logger def start_link(endpoint) do Supervisor.start_link(__MODULE__, endpoint) end @spec init({module | [module], integer}) :: {:ok, {:supervisor.sup_flags(), [:supervisor.child_spec()]}} | :ignore def init({endpoint, port}) do init({endpoint, port, []}) end @spec init({module | [module], integer, Keyword.t()}) :: {:ok, {:supervisor.sup_flags(), [:supervisor.child_spec()]}} | :ignore def init({endpoint, port, opts}) do check_deps_version() children = if Application.get_env(:grpc, :start_server, false) do [child_spec(endpoint, port, opts)] else [] end Supervisor.init(children, strategy: :one_for_one) end @doc """ Return a child_spec to start server. ## Options * `:cred` - a credential created by functions of `GRPC.Credential`, an insecure server will be created without this option """ @spec child_spec(atom | [atom], integer, Keyword.t()) :: Supervisor.Spec.spec() def child_spec(endpoint, port, opts \\ []) def child_spec(endpoint, port, opts) when is_atom(endpoint) do {endpoint, servers} = try do {endpoint, endpoint.__meta__(:servers)} rescue FunctionClauseError -> Logger.warn( "deprecated: servers as argument of GRPC.Server.Supervisor, please use GRPC.Endpoint" ) {nil, endpoint} end adapter = Keyword.get(opts, :adapter, @default_adapter) servers = GRPC.Server.servers_to_map(servers) adapter.child_spec(endpoint, servers, port, opts) end def child_spec(servers, port, opts) when is_list(servers) do adapter = Keyword.get(opts, :adapter, @default_adapter) servers = GRPC.Server.servers_to_map(servers) adapter.child_spec(nil, servers, port, opts) end defp check_deps_version() do # cowlib case :application.get_key(:cowlib, :vsn) do {:ok, vsn} -> ver = to_string(vsn) unless Version.match?(ver, ">= 2.9.0") do Logger.warn("cowlib should be >= 2.9.0, it's #{ver} now. See grpc's README for details") end _ -> :ok end rescue _ -> :ok end end