alfetahe / process-hub

Distributed processes manager and global process registry
GNU General Public License v3.0
62 stars 2 forks source link

Starting processes in Application.start causes mix commands to fail #6

Closed bjuretic closed 1 month ago

bjuretic commented 2 months ago

(moving this into a separate issue for easier tracking)

You're using the async_wait option but not actually waiting for the response with ProcessHub.await(), meaning the caller process will receive unhandled messages in its mailbox. You should either remove async_wait: true or wait for the child startup. I will make this clearer in the documentation.

Ok, I have tried this and it works, but there is something I would consider a bug if it is done this way. Consider the code in Application.start:

    sup_result = Supervisor.start_link(children, opts)

    # Start global processes

    ProcessHub.start_child(
      :services,
      %{id: :sessions, start: {UserSessions, :start_link, []}},
      async_wait: true
    )
    |> ProcessHub.await()

This runs fine if the node is started as part of a cluster. But if I want to run a simple mix command, e.g. mix ecto.reset it fails:

** (Mix) Could not start application myapp: exited in: MyApp.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (ArgumentError) errors were found at the given arguments:

  * 1st argument: the table identifier does not refer to an existing ETS table

            (stdlib 5.2.3) :ets.lookup(:"hub.services.local_storage", :distribution_strategy)
            (process_hub 0.2.6-alpha) lib/process_hub/service/storage.ex:32: ProcessHub.Service.Storage.get/2
            (process_hub 0.2.6-alpha) lib/process_hub/service/distributor.ex:186: ProcessHub.Service.Distributor.init_strategies/1
            (process_hub 0.2.6-alpha) lib/process_hub/service/distributor.ex:61: ProcessHub.Service.Distributor.init_children/3
            (myapp 0.1.0) lib/myapp/application.ex:64: MyApp.Application.start/2
            (kernel 9.2.4.1) application_master.erl:293: :application_master.start_it_old/4

Starting the app with iex with cookie and node name works fine.

From what I gather, it just expects the application to be ran in a cluster, and if fails when it cannot find node info. Error message could be better, but the main point is what would you recommend here on how to start the processes on Application.start while still being able to execute mix commands and tests (which also fail to run with the same error)?

(update) Actually even just starting the ProcessHub in Application.start with no child processes being started later by it causes the similar problem. Again running mix ecto.reset or running tests end with:

** (Mix) Could not start application myapp: MyApp.Application.start(:normal, []) returned an error: shutdown: failed to start child: :services
    ** (EXIT) ProcessHub.Initializer.init/1 returned a bad value: {:error, :local_node_not_alive}
alfetahe commented 1 month ago

Thank you for reporting the issue.

I have removed the restriction on starting as a distributed node, as it was no longer necessary. Additionally, I have added the ability to start child processes statically.

Example:

child_specs = for x <- 1..10 do
  %{
    id: :"my_process_#{x}",
    start: {MyProcess, :start_link, []}
  }
end

ProcessHub.child_spec(%ProcessHub{
  hub_id: :my_hub,
  child_specs: child_specs
})

I also realized that I forgot to publish the 0.2.6-alpha release.. The master branch was up to date, but the code was not published to Hex. The new version, 0.2.7-alpha, is now published.

bjuretic commented 1 month ago

Thanks! Static processes starting is working fine and there are no more issues with starting mix commands.