gen_rmq icon indicating copy to clipboard operation
gen_rmq copied to clipboard

[FEATURE] Pass options to init callback via start_link function

Open yunmikun2 opened this issue 2 years ago • 5 comments

Is your feature request related to a problem? Please describe.

There is no possibility to pass options to the process when starting it in a supervision tree. It would be nice to have gen_rmq acting like conventional elixir processes. The usage would look like this:

def start_link(opts) do
  {rmq_user, opts} = Keyword.pop!(opts, :rmq_user)
  {rmq_pass, opts} = Keyword.pop!(opts, :rmq_pass)

  children = [
    {MyApp.SomeConsumer, rmq_user: rmq_user, rmq_pass: rmq_pass}
  ]

  Supervisor.start_link(children, strategy: :one_to_one)
end

Then, in MyApp.SomeConsumer, we would just define the child_spec/1 and options' construction in the init/1:

defmodule MyApp.SomeConsumer do
  @behaviour GenRMQ.Consumer

  @doc false
  def child_spec(opts) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [opts]},
      type: :worker
    }
  end

  def start_link(opts) do
    GenRMQ.start_link(__MODULE__, opts, [])
  end

  @impl true
  def init(opts) do
    {rmq_user, opts} = Keyword.pop!(opts, :rmq_user)
    {rmq_pass, opts} = Keyword.pop!(opts, :rmq_pass)

    [
      connection: [
        username: rmq_user,
        password: rmq_pass
      ],
      # ...
    ]
  end

  # ...
end

The example above may look like the change is irrelevant, but if we have more processes working with rmq connections, we have no way to extract and pass them from one place. We always have to repeat the configuration extraction in each init/0 callback or switch to practices that are not that convenient (like moving the logic of looking up the configuration into a separate module).

Moreover, current behavior requires us to use configuration mechanisms with shared state (like Config) which is not desirable in tests and is bad for reusability.

Note that, to follow the conventions, we'd better implement __using__/1 macro, that would generate child_spec/1 for us, too, like GenServer and other primitives from std do. But, I guess, it's OK to have GenRMQ primitives as simple behaviours.

yunmikun2 avatar Jun 15 '22 19:06 yunmikun2

Also note that #130 states that these changes' been implemented, but I can find no trace of these. Guess it's because the PR was not linked to the issue. But still we sure don't have such a feature as of now.

yunmikun2 avatar Jun 15 '22 19:06 yunmikun2

@yunmikun2 thanks for the detailed issue including examples and all.

Just out of curiosity, and as motivation for the maintainers of this project, can you share more about for which project you are using gem_rmq?

spier avatar Jun 21 '22 10:06 spier

can you share more about for which project you are using gem_rmq?

@spier, it's a project at work so, I guess, I'm not at liberty to get into details. Sorry. :sweat_smile:

yunmikun2 avatar Jun 27 '22 11:06 yunmikun2

Hi is it possible to create multiple topics using gen_rmq?

I am trying to publish data to 3 different separate topics, is it possible to do so with gen_rmq?

ijunaid8989 avatar Aug 05 '22 13:08 ijunaid8989

Hi is it possible to create multiple topics using gen_rmq?

I am trying to publish data to 3 different separate topics, is it possible to do so with gen_rmq?

Hi @ijunaid8989 and excuse my slow response.

It looks like your question is not directly to this issue here, is it? Would you mind opening a new issue for this so that we keep the conversations separate? Thank you

spier avatar Aug 26 '22 13:08 spier