From c472f3ea46a5dd5f62bb12b5857e779ae0d74dc5 Mon Sep 17 00:00:00 2001 From: William Boman Date: Sat, 16 Apr 2022 01:43:09 +0200 Subject: fix(async): slightly better support for nested coroutine contexts (#600) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(async): only dispatch first failure in a.wait_all * add InstallContext:run_concurrently This is needed due to how multiple coroutine contexts are used in a hierchical structure, and the async coroutine dispatcher loses this hierchical context inside callback functions invoked via FFI (I… assume?). --- tests/core/installer_spec.lua | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'tests/core/installer_spec.lua') diff --git a/tests/core/installer_spec.lua b/tests/core/installer_spec.lua index 75911416..cf8e8795 100644 --- a/tests/core/installer_spec.lua +++ b/tests/core/installer_spec.lua @@ -1,11 +1,17 @@ local spy = require "luassert.spy" local match = require "luassert.match" local fs = require "nvim-lsp-installer.core.fs" +local a = require "nvim-lsp-installer.core.async" local installer = require "nvim-lsp-installer.core.installer" local InstallContext = require "nvim-lsp-installer.core.installer.context" local process = require "nvim-lsp-installer.process" local Optional = require "nvim-lsp-installer.core.optional" +local function timestamp() + local seconds, microseconds = vim.loop.gettimeofday() + return (seconds * 1000) + math.floor(microseconds / 1000) +end + describe("installer", function() it( "should call installer", @@ -89,4 +95,42 @@ describe("installer", function() ) end) ) + + it( + "should run async functions concurrently", + async_test(function() + spy.on(fs, "write_file") + local destination_dir = ("%s/installer_spec_concurrent"):format(os.getenv "INSTALL_ROOT_DIR") + local ctx = InstallContext.new { + name = "installer_spec_receipt", + destination_dir = destination_dir, + boundary_path = os.getenv "INSTALL_ROOT_DIR", + stdio_sink = process.empty_sink(), + requested_version = Optional.empty(), + } + local capture = spy.new() + local start = timestamp() + installer.run_installer(ctx, function(c) + capture(c:run_concurrently { + function() + a.sleep(100) + return installer.context() + end, + function() + a.sleep(100) + return "two" + end, + function() + a.sleep(100) + return "three" + end, + }) + c.receipt:with_primary_source(c.receipt.npm "my-pkg") + end) + local stop = timestamp() + local grace_ms = 25 + assert.is_true((stop - start) >= (100 - grace_ms)) + assert.spy(capture).was_called_with(match.is_ref(ctx), "two", "three") + end) + ) end) -- cgit v1.2.3-70-g09d2