Skip to content

Commit

Permalink
feat: progress messages for workspace indexing (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhanberg authored Aug 13, 2023
1 parent 6098bad commit 09883bc
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 15 deletions.
5 changes: 5 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Config

config :next_ls, :indexing_timeout, 100

import_config "#{config_env()}.exs"
1 change: 1 addition & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import Config
1 change: 1 addition & 0 deletions config/prod.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import Config
1 change: 1 addition & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import Config
1 change: 1 addition & 0 deletions lib/next_ls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ defmodule NextLS do
{NextLS.Runtime.Supervisor,
path: Path.join(working_dir, ".elixir-tools"),
name: name,
lsp: lsp,
registry: lsp.assigns.registry,
logger: lsp.assigns.logger,
runtime: [
Expand Down
14 changes: 12 additions & 2 deletions lib/next_ls/db.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule NextLS.DB do
@moduledoc false
@moduledoc nil
use GenServer

import __MODULE__.Query
Expand All @@ -26,6 +26,7 @@ defmodule NextLS.DB do
file = Keyword.fetch!(args, :file)
registry = Keyword.fetch!(args, :registry)
logger = Keyword.fetch!(args, :logger)
activity = Keyword.fetch!(args, :activity)
Registry.register(registry, :databases, %{})
{:ok, conn} = Exqlite.Basic.open(file)

Expand All @@ -35,11 +36,14 @@ defmodule NextLS.DB do
%{
conn: conn,
file: file,
logger: logger
logger: logger,
activity: activity
}}
end

def handle_call({:query, query, args}, _from, %{conn: conn} = s) do
{:message_queue_len, count} = Process.info(self(), :message_queue_len)
NextLS.DB.Activity.update(s.activity, count)
rows = __query__({conn, s.logger}, query, args)

{:reply, rows, s}
Expand Down Expand Up @@ -74,6 +78,9 @@ defmodule NextLS.DB do
end

def handle_cast({:insert_symbol, symbol}, %{conn: conn} = s) do
{:message_queue_len, count} = Process.info(self(), :message_queue_len)
NextLS.DB.Activity.update(s.activity, count)

%{
module: mod,
module_line: module_line,
Expand Down Expand Up @@ -128,6 +135,9 @@ defmodule NextLS.DB do
end

def handle_cast({:insert_reference, reference}, %{conn: conn} = s) do
{:message_queue_len, count} = Process.info(self(), :message_queue_len)
NextLS.DB.Activity.update(s.activity, count)

%{
meta: meta,
identifier: identifier,
Expand Down
56 changes: 56 additions & 0 deletions lib/next_ls/db/activity.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
defmodule NextLS.DB.Activity do
@moduledoc false
@behaviour :gen_statem

def child_spec(opts) do
%{
id: opts[:name] || opts[:id],
start: {__MODULE__, :start_link, [opts]}
}
end

def start_link(args) do
:gen_statem.start_link({:local, Keyword.get(args, :name)}, __MODULE__, Keyword.drop(args, [:name]), [])
end

def update(statem, count), do: :gen_statem.cast(statem, count)

@impl :gen_statem
def callback_mode, do: :state_functions

@impl :gen_statem
def init(args) do
logger = Keyword.fetch!(args, :logger)
lsp = Keyword.fetch!(args, :lsp)
timeout = Keyword.fetch!(args, :timeout)

{:ok, :waiting, %{count: 0, logger: logger, lsp: lsp, timeout: timeout, token: nil}}
end

def active(:cast, 0, data) do
{:keep_state, %{data | count: 0}, [{:state_timeout, data.timeout, :waiting}]}
end

def active(:cast, mailbox_count, %{count: 0} = data) do
{:keep_state, %{data | count: mailbox_count}, [{:state_timeout, :cancel}]}
end

def active(:cast, mailbox_count, data) do
{:keep_state, %{data | count: mailbox_count}, []}
end

def active(:state_timeout, :waiting, data) do
NextLS.Progress.stop(data.lsp, data.token, "Finished indexing!")
{:next_state, :waiting, %{data | token: nil}}
end

def waiting(:cast, 0, _data) do
:keep_state_and_data
end

def waiting(:cast, mailbox_count, data) do
token = NextLS.Progress.token()
NextLS.Progress.start(data.lsp, token, "Indexing!")
{:next_state, :active, %{data | count: mailbox_count, token: token}}
end
end
10 changes: 7 additions & 3 deletions lib/next_ls/runtime/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,25 @@ defmodule NextLS.Runtime.Supervisor do
@impl true
def init(init_arg) do
name = init_arg[:name]
lsp = init_arg[:lsp]
registry = init_arg[:registry]
logger = init_arg[:logger]
hidden_folder = init_arg[:path]
File.mkdir_p!(hidden_folder)
File.write!(Path.join(hidden_folder, ".gitignore"), "*\n")

symbol_table_name = :"symbol-table-#{name}"
db_name = :"db-#{name}"
sidecar_name = :"sidecar-#{name}"
db_activity = :"db-activity-#{name}"

Registry.register(registry, :runtime_supervisors, %{name: name})

children = [
{NextLS.DB, logger: logger, file: "#{hidden_folder}/nextls.db", registry: registry, name: db_name},
{NextLS.Runtime.Sidecar, name: sidecar_name, db: db_name, symbol_table: symbol_table_name},
{NextLS.Runtime.Sidecar, name: sidecar_name, db: db_name},
{NextLS.DB.Activity,
logger: logger, name: db_activity, lsp: lsp, timeout: Application.get_env(:next_ls, :indexing_timeout)},
{NextLS.DB,
logger: logger, file: "#{hidden_folder}/nextls.db", registry: registry, name: db_name, activity: db_activity},
{NextLS.Runtime, init_arg[:runtime] ++ [name: name, registry: registry, parent: sidecar_name, db: db_name]}
]

Expand Down
14 changes: 7 additions & 7 deletions test/next_ls/definition_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule NextLS.DefinitionTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -96,7 +96,7 @@ defmodule NextLS.DefinitionTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -132,7 +132,7 @@ defmodule NextLS.DefinitionTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -228,7 +228,7 @@ defmodule NextLS.DefinitionTest do
assert :ok == notify(client, %{method: "initialized", jsonrpc: "2.0", params: %{}})
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -262,7 +262,7 @@ defmodule NextLS.DefinitionTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -298,7 +298,7 @@ defmodule NextLS.DefinitionTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down Expand Up @@ -369,7 +369,7 @@ defmodule NextLS.DefinitionTest do
assert :ok == notify(client, %{method: "initialized", jsonrpc: "2.0", params: %{}})
assert_request(client, "client/registerCapability", fn _params -> nil end)
assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

uri = uri(bar)

Expand Down
2 changes: 2 additions & 0 deletions test/next_ls/references_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ defmodule NextLS.ReferencesTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)
assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

request(client, %{
method: "textDocument/references",
Expand Down Expand Up @@ -78,6 +79,7 @@ defmodule NextLS.ReferencesTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)
assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

request(client, %{
method: "textDocument/references",
Expand Down
6 changes: 3 additions & 3 deletions test/next_ls_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ defmodule NextLSTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

request client, %{
method: "workspace/symbol",
Expand Down Expand Up @@ -331,7 +331,7 @@ defmodule NextLSTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

request client, %{
method: "workspace/symbol",
Expand Down Expand Up @@ -387,7 +387,7 @@ defmodule NextLSTest do
assert_request(client, "client/registerCapability", fn _params -> nil end)

assert_is_ready(context, "my_proj")
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
assert_notification "$/progress", %{"value" => %{"kind" => "end", "message" => "Finished indexing!"}}

request client, %{method: "workspace/symbol", id: 2, jsonrpc: "2.0", params: %{query: ""}}

Expand Down
1 change: 1 addition & 0 deletions test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Logger.configure(level: :warning)

timeout =
if System.get_env("CI", "false") == "true" do
Application.put_env(:next_ls, :indexing_timeout, 500)
60_000
else
30_000
Expand Down

0 comments on commit 09883bc

Please sign in to comment.