diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 49102ae6..3aa8f98e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -9,22 +9,22 @@ permissions: pull-requests: write jobs: - commitlint: - runs-on: ubuntu-latest - name: commitlint + # commitlint: + # runs-on: ubuntu-latest + # name: commitlint - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install Deps - run: yarn install - - name: Lint PR Title - run: yarn commitlint --from "${{ github.event.before }}" + # steps: + # - uses: actions/checkout@v4 + # with: + # fetch-depth: 0 + # - name: Install Deps + # run: yarn install + # - name: Lint PR Title + # run: yarn commitlint --from "${{ github.event.before }}" release: name: release - needs: commitlint + # needs: commitlint runs-on: ubuntu-latest outputs: release_created: ${{ steps.release.outputs.release_created }} diff --git a/lib/next_ls/runtime.ex b/lib/next_ls/runtime.ex index 4ca68420..749122d6 100644 --- a/lib/next_ls/runtime.ex +++ b/lib/next_ls/runtime.ex @@ -231,22 +231,32 @@ defmodule NextLS.Runtime do true <- connect(node, port, 120) do NextLS.Logger.info(logger, "Connected to node #{node}") - :next_ls - |> :code.priv_dir() - |> Path.join("monkey/_next_ls_private_compiler.ex") - |> then(&:rpc.call(node, Code, :compile_file, [&1])) - |> tap(fn - {:badrpc, error} -> - NextLS.Logger.error(logger, "Bad RPC call to node #{node}: #{inspect(error)}") - send(me, {:cancel, error}) - - _ -> - :ok - end) - - {:ok, _} = :rpc.call(node, :_next_ls_private_compiler, :start, []) - - send(me, {:node, node}) + result = + :next_ls + |> :code.priv_dir() + |> Path.join("monkey/_next_ls_private_compiler.ex") + |> then(fn path -> + if await_config_table(node, 5) do + :rpc.call(node, Code, :compile_file, [path]) + else + {:badrpc, "internal ets table not found"} + end + end) + |> then(fn + {:badrpc, error} -> + NextLS.Logger.error(logger, "Bad RPC call to node #{node}: #{inspect(error)}") + send(me, {:cancel, error}) + :error + + _ -> + :ok + end) + + if result == :ok do + {:ok, _} = :rpc.call(node, :_next_ls_private_compiler, :start, []) + + send(me, {:node, node}) + end else error -> send(me, {:cancel, error}) @@ -275,6 +285,20 @@ defmodule NextLS.Runtime do end end + defp await_config_table(_node, 0) do + false + end + + defp await_config_table(node, attempts) do + # this is an Elixir implementation detail, handle with care + if :undefined == :rpc.call(node, :ets, :whereis, [:elixir_config]) do + Process.sleep(100) + await_config_table(node, attempts - 1) + else + true + end + end + @impl GenServer def handle_call(:ready?, _from, state) when is_ready(state) do {:reply, true, state} diff --git a/priv/monkey/_next_ls_private_compiler.ex b/priv/monkey/_next_ls_private_compiler.ex index 3e34a6b1..d673b3ea 100644 --- a/priv/monkey/_next_ls_private_compiler.ex +++ b/priv/monkey/_next_ls_private_compiler.ex @@ -1032,14 +1032,13 @@ defmodule :_next_ls_private_compiler do @moduledoc false def start do + Code.put_compiler_option(:parser_options, columns: true, token_metadata: true) + children = [ :_next_ls_private_compiler_worker ] - # See https://hexdocs.pm/elixir/Supervisor.html - # for other strategies and supported options - opts = [strategy: :one_for_one, name: :_next_ls_private_application_supervisor] - {:ok, pid} = Supervisor.start_link(children, opts) + {:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one, name: :_next_ls_private_application_supervisor) Process.unlink(pid) {:ok, pid} end @@ -1049,7 +1048,6 @@ defmodule :_next_ls_private_compiler do def compile do # keep stdout on this node Process.group_leader(self(), Process.whereis(:user)) - Code.put_compiler_option(:parser_options, columns: true, token_metadata: true) Code.put_compiler_option(:tracers, [NextLSPrivate.DepTracer | @tracers])