elixir-grpc / grpc-reflection

elixir graph reflection support
Apache License 2.0
9 stars 6 forks source link

Reflection State is split up #17

Closed mjheilmann closed 9 months ago

mjheilmann commented 10 months ago

The reflection state is constructed in Builder, read in Lookup, and defined in Agent. This is coupling and not very opaque.

The reflection state should be a separable module defining the internal state, exposing functions to either mutate a state by adding an entry, or read a state by checking an existing state struct for a given entry. This would prevent the state internals from having to be known and checked in multiple modules.

Example

defmodule GrpcReflection.Service.State do
  defstruct services: [], files: %{}, symbols: %{}, extensions: %{}

    @type t :: %__MODULE__{
          services: list(module()),
          files: %{optional(binary()) => descriptor_t()},
          symbols: %{optional(binary()) => descriptor_t()},
          extensions: %{optional(binary()) => list(integer())}
      }

  @callback add_service(state :: t(), module :: atom()) :: t()
  @callback lookup_services(state :: t()) :: list(atom())

  @callback add_filename(state :: t(), filename :: binary(), descriptor :: descriptor_t()) :: t()
  @callback lookup_filename(state :: t(), file :: binary()) :: {:ok, descriptor_t()} || :not_found

  @callback add_symbol(state :: t(), symbol :: binary(), descriptor :: descriptor_t()) :: t()
  @callback lookup_symbol(state :: t(), symbol :: binary()) :: {:ok, descriptor_t()} || :not_found

  @callback add_extension(state :: t(), filename :: binary(), descriptor :: descriptor_t()) :: t()
  @callback lookup_extension_numbers(state :: t(), <... lookup params>) :: {:ok, <extensions>} || :not_found
end

This will replace the Lookup module, and be called by the Builder module during construction, removing state implementation details from the Builder and simplifying its code