Skip to content

👍 Async server start stop #378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 1, 2024
Merged

👍 Async server start stop #378

merged 5 commits into from
Jul 1, 2024

Conversation

Milly
Copy link
Contributor

@Milly Milly commented Jun 29, 2024

  • Add new denops-variable:
    • g:denops#server#close_timeout
  • Add new state for denops#server#status():
    • closing
    • closed
  • Change behavior denops-function:
    • denops#server#start() can now be called even when status is closing. In that case, the status will become stopped and then restart asynchronously.
    • denops#server#start() is changed to asynchronously.
      • It can now be called even when status is closing. In that case, the status will become stopped and then restart asynchronously.
      • If process startup fails, it does not retrie synchronously (does not use retry_threshold), it retries asynchronously (uses restart_threshold).
    • denops#server#stop() is changed to asynchronously.
      • It waits for the server to close gracefully, and force terminate if timeouted.
    • denops#server#restart() is changed to asynchronously.
      • Perform the stop and start steps above.

Summary by CodeRabbit

  • New Features

    • Enhanced error handling for job executions, especially on Windows environments.
    • Introduced new server management functions, including status checks and forced channel closures.
    • Added a close() method to the Service interface for better resource management.
    • Improved stream handling with additional parameters for stdout and stderr.
  • Bug Fixes

    • Addressed issues with job failures and callbacks by restructuring logic and adding error handlers.
  • Refactor

    • Replaced for loops with while loops for better connection retries.
    • Refactored function signatures to enhance parameter handling and improve code readability.
  • Documentation

    • Updated documentation to reflect changes in server behavior, timeout settings, and new functionalities.
  • Tests

    • Added new test cases for server management scenarios, including status transitions and stream handling.
    • Updated existing tests to align with new function signatures and enhanced destructuring of parameters.

Copy link

coderabbitai bot commented Jun 29, 2024

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update enhances the Denops plugin by introducing robust error handling, improved channel management, and streamlined server behaviors. Key changes include adding error callbacks, refining connection retries, enhancing server start and stop mechanisms, and expanding test utilities. These modifications aim for better reliability, consistency in server operations, and improved test coverage.

Changes

Files Change Summary
autoload/denops/_internal/job.vim Added error handling for job execution, adjusted callbacks to receive job objects.
autoload/denops/_internal/server/chan.vim Replaced for loop with while for retries, added timeout for channel close, new force close functions.
autoload/denops/_internal/server/proc.vim Simplified server startup, removed retry logic, updated autocmd event names.
autoload/denops/server.vim Added new status constants and functions for server management, introduced new variables for server state management.
denops/@denops-private/host.ts Added close() method to Service interface, updated invoke() function.
denops/.../host/nvim_test.ts Updated function parameters to object destructuring, added close method to Service.
denops/.../host/vim_test.ts Similar updates as nvim_test.ts, added close method to service.
denops/.../host_test.ts Introduced close method in the service object, added corresponding test cases.
denops/.../testutil/host.ts Added stdout and stderr parameters to HostFn and TestFn, updated related functions.
denops/.../testutil/shared_server.ts Modified to handle stderr, added new channels for stdout and stderr.
denops/.../shared_server_test.ts Added new assertions and conditions for verbose output handling, new tests for verbose scenarios.
denops/.../shared_server_test_no_verbose.ts Introduced new file with test scenarios involving a brief delay.
denops/.../shared_server_test_verbose_true.ts Introduced new file with test scenarios for verbose flag set to true.
denops/.../with.ts Enhanced stream and process communication, updated command execution, improved error handling and cleanup.
denops/.../worker.ts Updated command in connectHost to trigger DenopsSystemReady autocmd event.
denops/.../worker_test.ts Updated doautocmd function parameter to DenopsSystemReady in multiple instances.
doc/denops.txt Updated descriptions for restart thresholds, reconnect intervals, close timeout settings, and server functions.
tests/.../plugin_test.ts Updated function definitions for object destructuring of the host parameter.
tests/.../server_test.ts Improved test logic, asynchronous handling, error messages, and status transitions for server operations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DenopsPlugin
    participant Job
    participant ServerChan
    participant ServerProc
    participant TestUtil
    User->>DenopsPlugin: Initialize
    DenopsPlugin->>ServerProc: Start server
    ServerProc->>ServerChan: Establish connection
    ServerChan->>DenopsPlugin: Connection established
    User->>DenopsPlugin: Run Command
    DenopsPlugin->>Job: Execute job
    Job->>DenopsPlugin: Job result
    User->>DenopsPlugin: Stop server
    DenopsPlugin->>ServerProc: Shutdown server
    ServerProc->>ServerChan: Close channels
    ServerChan->>TestUtil: Cleanup
Loading

Poem

Amidst the code in Vim's delightful land,
Denops evolves with error handling grand.
Channels close with grace, no time to wait,
Jobs will run, never check too late.
Servers start and stop, reconnect anew,
In tests we trust, the bugs we now subdue.
Celebrate with hops, our journey never ends,
For each line of code, a rabbit-send depends.

  (\(\   
 ( -.-)  
o_(")(") 🍂

Tip

Early access features: disabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jun 29, 2024

Codecov Report

Attention: Patch coverage is 87.34177% with 10 lines in your changes missing coverage. Please review.

Project coverage is 92.30%. Comparing base (dd6ca3c) to head (f766e94).

Files Patch % Lines
denops/@denops-private/testutil/with.ts 82.92% 7 Missing ⚠️
denops/@denops-private/testutil/host.ts 60.00% 2 Missing ⚠️
denops/@denops-private/testutil/shared_server.ts 96.15% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           v7-pre     #378      +/-   ##
==========================================
- Coverage   92.51%   92.30%   -0.22%     
==========================================
  Files          21       21              
  Lines        1242     1286      +44     
  Branches      142      142              
==========================================
+ Hits         1149     1187      +38     
- Misses         90       96       +6     
  Partials        3        3              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Milly Milly force-pushed the async-server-start-stop branch from 2484032 to 97cf13a Compare June 29, 2024 05:00
Milly added 2 commits June 29, 2024 14:08
- Change helper argument to record.
- Add `stdout` and `stderr` helper properties.
@Milly Milly force-pushed the async-server-start-stop branch from 97cf13a to 6992d56 Compare June 29, 2024 05:08
@lambdalisue lambdalisue marked this pull request as draft June 29, 2024 17:57
@Milly Milly force-pushed the async-server-start-stop branch from 6992d56 to 5e7e3c2 Compare June 30, 2024 04:55
@Milly
Copy link
Contributor Author

Milly commented Jun 30, 2024

I committed 👍 remove retry_interval, retry_threshold from proc#start() to make it easier to see the diff, and after review I want to amend it to 👍 change denops#server#start and ...#stop to asynchronous because it breaks tests.

@Milly Milly requested a review from lambdalisue June 30, 2024 05:19
@Milly
Copy link
Contributor Author

Milly commented Jun 30, 2024

@coderabbitai review

Copy link

coderabbitai bot commented Jun 30, 2024

Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

coderabbitai bot commented Jun 30, 2024

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

Commits

Files that changed from the base of the PR and between dd6ca3c and 5e7e3c2.

Files selected for processing (19)
  • autoload/denops/_internal/job.vim (3 hunks)
  • autoload/denops/_internal/server/chan.vim (4 hunks)
  • autoload/denops/_internal/server/proc.vim (6 hunks)
  • autoload/denops/server.vim (4 hunks)
  • denops/@denops-private/host.ts (3 hunks)
  • denops/@denops-private/host/nvim_test.ts (1 hunks)
  • denops/@denops-private/host/vim_test.ts (1 hunks)
  • denops/@denops-private/host_test.ts (2 hunks)
  • denops/@denops-private/testutil/host.ts (3 hunks)
  • denops/@denops-private/testutil/shared_server.ts (3 hunks)
  • denops/@denops-private/testutil/shared_server_test.ts (1 hunks)
  • denops/@denops-private/testutil/shared_server_test_no_verbose.ts (1 hunks)
  • denops/@denops-private/testutil/shared_server_test_verbose_true.ts (1 hunks)
  • denops/@denops-private/testutil/with.ts (4 hunks)
  • denops/@denops-private/worker.ts (1 hunks)
  • denops/@denops-private/worker_test.ts (7 hunks)
  • doc/denops.txt (5 hunks)
  • tests/denops/plugin_test.ts (3 hunks)
  • tests/denops/server_test.ts (4 hunks)
 ___________________________
< Debugging like it's 2099. >
 ---------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

Tip

Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.
  • OSS projects are always opted into early access features.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between dd6ca3c and 5e7e3c2.

Files selected for processing (19)
  • autoload/denops/_internal/job.vim (3 hunks)
  • autoload/denops/_internal/server/chan.vim (4 hunks)
  • autoload/denops/_internal/server/proc.vim (6 hunks)
  • autoload/denops/server.vim (4 hunks)
  • denops/@denops-private/host.ts (3 hunks)
  • denops/@denops-private/host/nvim_test.ts (1 hunks)
  • denops/@denops-private/host/vim_test.ts (1 hunks)
  • denops/@denops-private/host_test.ts (2 hunks)
  • denops/@denops-private/testutil/host.ts (3 hunks)
  • denops/@denops-private/testutil/shared_server.ts (3 hunks)
  • denops/@denops-private/testutil/shared_server_test.ts (1 hunks)
  • denops/@denops-private/testutil/shared_server_test_no_verbose.ts (1 hunks)
  • denops/@denops-private/testutil/shared_server_test_verbose_true.ts (1 hunks)
  • denops/@denops-private/testutil/with.ts (4 hunks)
  • denops/@denops-private/worker.ts (1 hunks)
  • denops/@denops-private/worker_test.ts (7 hunks)
  • doc/denops.txt (5 hunks)
  • tests/denops/plugin_test.ts (3 hunks)
  • tests/denops/server_test.ts (4 hunks)
Files skipped from review due to trivial changes (1)
  • autoload/denops/_internal/server/proc.vim
Additional context used
Biome
denops/@denops-private/worker.ts

[error] 43-45: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)

GitHub Check: codecov/patch
denops/@denops-private/testutil/shared_server.ts

[warning] 67-67: denops/@denops-private/testutil/shared_server.ts#L67
Added line #L67 was not covered by tests

denops/@denops-private/testutil/with.ts

[warning] 120-122: denops/@denops-private/testutil/with.ts#L120-L122
Added lines #L120 - L122 were not covered by tests


[warning] 141-142: denops/@denops-private/testutil/with.ts#L141-L142
Added lines #L141 - L142 were not covered by tests

LanguageTool
doc/denops.txt

[grammar] ~77-~77: The verb form ‘install’ does not seem to be suitable in this context.
Context: ...2345 < Note that there is a plugin that install startup scripts of the shared server fo...

(A_NN_THAT_VB)


[style] ~119-~119: ‘prior to’ might be wordy. Consider a shorter alternative.
Context: ...hown. This variable must be configured prior to denops initialization. Default: 0 *g:...

(EN_WORDINESS_PREMIUM_PRIOR_TO)


[uncategorized] ~141-~141: Possible missing article found.
Context: ...oid infinite errors. Denops will reset internal counter when the process keeps running ...

(AI_HYDRA_LEO_MISSING_THE)

Additional comments not posted (62)
denops/@denops-private/testutil/shared_server_test_no_verbose.ts (2)

1-2: Imports look good.

The import statements for delay and useSharedServer are correct and necessary for the functionality.


4-7: Ensure proper cleanup.

The use of await using _server = await useSharedServer(); is correct, but ensure that _server is properly cleaned up after the delay.

Verification successful

Proper cleanup is ensured.

The useSharedServer function includes a Symbol.asyncDispose method that calls an abort function to handle cleanup. This confirms that _server is properly cleaned up after the delay.

  • denops/@denops-private/testutil/shared_server.ts:
    • Implementation of useSharedServer with proper cleanup logic.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `_server` is properly cleaned up after the delay.

# Test: Search for `useSharedServer` usage. Expect: Proper cleanup.
rg --type typescript $'useSharedServer'

Length of output: 73



Script:

#!/bin/bash
# Description: Verify that `_server` is properly cleaned up after the delay.

# Test: Search for `useSharedServer` usage. Expect: Proper cleanup.
rg --glob '*.ts' 'useSharedServer'

Length of output: 2302



Script:

#!/bin/bash
# Description: Extract the implementation of `useSharedServer` to verify cleanup logic.

# Extract the function implementation from `shared_server.ts`
ast-grep --lang typescript --pattern $'export async function useSharedServer($_) {
  $$$
}' 

Length of output: 92



Script:

#!/bin/bash
# Description: Extract the implementation of `useSharedServer` to verify cleanup logic.

# Locate the definition of `useSharedServer` in `shared_server.ts`
rg 'export async function useSharedServer' -A 20 denops/@denops-private/testutil/shared_server.ts

Length of output: 606



Script:

#!/bin/bash
# Description: Extract the full implementation of `useSharedServer` to verify cleanup logic.

# Locate the definition of `useSharedServer` in `shared_server.ts` and extract more lines
rg 'export async function useSharedServer' -A 50 denops/@denops-private/testutil/shared_server.ts

Length of output: 1575



Script:

#!/bin/bash
# Description: Extract the full implementation of `useSharedServer` to verify cleanup logic.

# Locate the definition of `useSharedServer` in `shared_server.ts` and extract more lines
rg 'export async function useSharedServer' -A 100 denops/@denops-private/testutil/shared_server.ts

Length of output: 2057

denops/@denops-private/testutil/shared_server_test_verbose_true.ts (2)

1-2: Imports look good.

The import statements for delay and useSharedServer are correct and necessary for the functionality.


4-7: Ensure proper cleanup with verbose option.

The use of await using _server = await useSharedServer({ verbose: true }); is correct, but ensure that _server is properly cleaned up after the delay.

tests/denops/plugin_test.ts (3)

15-15: Function signature updated correctly.

The function signature now destructures the host object, which improves clarity.


24-24: Function signature updated correctly.

The function signature now destructures the host object, which improves clarity.


45-45: Function signature updated correctly.

The function signature now destructures the host object, which improves clarity.

denops/@denops-private/testutil/host.ts (5)

6-10: Type definition updated correctly.

The HostFn type now includes stdout and stderr streams, which is necessary for improved stream handling.


24-26: Function updated correctly for Vim mode.

The withHost function now handles stdout and stderr streams for Vim mode correctly.


33-35: Function updated correctly for Neovim mode.

The withHost function now handles stdout and stderr streams for Neovim mode correctly.


43-48: Type definition updated correctly.

The TestFn type now includes stdout and stderr streams, which is necessary for improved stream handling.


77-77: Function updated correctly for test mode.

The testHost function now handles stdout and stderr streams for test mode correctly.

denops/@denops-private/host.ts (2)

86-87: LGTM!

The invoke function correctly handles the new close method.


62-62: Ensure the close method is implemented correctly.

The close method has been added to the Service interface. Verify that this method is correctly implemented in all classes that implement this interface.

autoload/denops/_internal/job.vim (2)

65-72: Ensure error handling improvements are correct.

The error handling improvements in the s:start function for Vim are consistent with the existing logic. Verify that the error handling is correctly implemented.

Verification successful

Error handling improvements are correctly implemented.

The error handling improvements in the s:start function for Vim are consistent with the existing logic and correctly implemented.

  • autoload/denops/_internal/job.vim:
    • Lines around function! s:start(args, options) abort
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the error handling improvements in the `s:start` function for Vim.

# Test: Search for the `s:start` function implementation. Expect: Only occurances of the `s:start` function with improved error handling.
ast-grep --lang vim --pattern $'function! s:start($_, $_) abort\n  $$$\n  if $_->job_status() ==# "fail"\n    $$$\n  endif\n  return $_\nendfunction'

Length of output: 251



Script:

#!/bin/bash
# Description: Verify the error handling improvements in the `s:start` function for Vim.

# Search for the `s:start` function implementation in the codebase.
rg 'function! s:start' --context 10

Length of output: 4274


27-32: Ensure error handling improvements are correct.

The error handling improvements in the s:start function for Neovim are consistent with the existing logic. Verify that the error handling is correctly implemented.

Verification successful

Ensure error handling improvements are correct.

The error handling improvements in the s:start function for Neovim are consistent with the existing logic. The error handling is correctly implemented as follows:

  • The try-catch block ensures that if jobstart fails, the on_exit callback is executed with appropriate parameters.
  • The catch block specifically addresses the scenario where the command is not executable by calling timer_start with a zero delay to invoke on_exit.

The implementation correctly handles errors and ensures the on_exit callback is called when necessary.

  • File: autoload/denops/_internal/job.vim
  • Lines: 27-32
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the error handling improvements in the `s:start` function for Neovim.

# Test: Search for the `s:start` function implementation. Expect: Only occurances of the `s:start` function with improved error handling.
ast-grep --lang vim --pattern $'function! s:start($_, $_) abort\n  $$$\n  try\n    $$$\n  catch\n    $$$\n  endtry\nendfunction'

Length of output: 229



Script:

#!/bin/bash
# Description: Verify the error handling improvements in the `s:start` function for Neovim.

# Test: Search for the `s:start` function implementation and display its code.
rg --pcre2 -A 5 -B 5 'function! s:start\('

Length of output: 2259



Script:

#!/bin/bash
# Description: Verify the error handling improvements in the `s:start` function for Neovim.

# Test: Display full implementations of the `s:start` functions in `autoload/denops/_internal/job.vim`.
rg --pcre2 -A 50 'function! s:start\(' autoload/denops/_internal/job.vim

Length of output: 2505

denops/@denops-private/worker.ts (1)

82-86: Ensure the modification in the connectHost function is correct.

The modification in the connectHost function changes the command executed by host.call. Verify that this modification is correct and consistent with the existing logic.


<details>
<summary>Verification successful</summary>



---

<!-- Monologue:
[task 1/1] The task is to verify the modification in the `connectHost` function.
[observations] The output shows the `connectHost` function definition and multiple `host.call` usages in the `denops/@denops-private/worker.ts` file. Specifically, the `connectHost` function is defined, and it includes a `host.call` usage.
[analysis] The presence of the `connectHost` function and the `host.call` usage indicates that the modification is located within this function. The relevant snippet from the original review comment aligns with the `host.call` usage found in the `connectHost` function.
[actions] Conclude that the modification in the `connectHost` function is correct and consistent with the existing logic, as it matches the expected pattern and usage.
-->
**Modification in the `connectHost` function is correct and consistent with the existing logic.**

- The `connectHost` function is defined in `denops/@denops-private/worker.ts`.
- The `host.call` usage within this function aligns with the expected pattern.



</details>


<details>
<summary>Scripts executed</summary>

The following scripts were executed for the analysis:



---

Script:
```shell
#!/bin/bash
# Description: Verify the modification in the `connectHost` function.

# Test: Search for the `connectHost` function implementation. Expect: Only occurances of the `connectHost` function with the modified `host.call` command.
ast-grep --lang typescript --pattern $'async function connectHost() {\n  $$$\n  await host.call("execute", "doautocmd <nomodeline> User DenopsSystemReady", "", "");\n  $$$\n}'

Length of output: 172



Script:

#!/bin/bash
# Description: Search for the `connectHost` function in the codebase.

# Test: Search for the `connectHost` function definition.
ast-grep --lang typescript --pattern $'async function connectHost() {\n  $$$\n}'

# Test: Search for occurrences of `host.call` in the codebase.
ast-grep --lang typescript --pattern $'host.call($_, $_, $_, $_)'

Length of output: 146



Script:

#!/bin/bash
# Description: Search for any function definitions and occurrences of `host.call` in the codebase.

# Test: Search for any function definitions in the codebase.
ast-grep --lang typescript --pattern $'function $_($$) {\n  $$$\n}'

# Test: Search for any occurrences of `host.call` in the codebase.
rg 'host.call'

Length of output: 13729



Script:

#!/bin/bash
# Description: Search for function definitions within the `denops/@denops-private/worker.ts` file.

# Test: Search for function definitions in the `denops/@denops-private/worker.ts` file.
ast-grep --lang typescript --pattern $'function $_($$) {\n  $$$\n}' denops/@denops-private/worker.ts

Length of output: 99



Script:

#!/bin/bash
# Description: Search for all function definitions, including arrow functions and class methods, within the `denops/@denops-private/worker.ts` file.

# Test: Search for all function definitions in the `denops/@denops-private/worker.ts` file.
ast-grep --lang typescript --pattern $'const $_ = ($$) => {\n  $$$\n}' denops/@denops-private/worker.ts

# Test: Search for class methods in the `denops/@denops-private/worker.ts` file.
ast-grep --lang typescript --pattern $'$_($_) {\n  $$$\n}' denops/@denops-private/worker.ts

Length of output: 632



Script:

#!/bin/bash
# Description: Search for all function definitions and `host.call` usages within the `denops/@denops-private/worker.ts` file.

# Test: Search for any function definitions in the `denops/@denops-private/worker.ts` file.
rg 'function |const |async |class ' denops/@denops-private/worker.ts

# Test: Search for any `host.call` usages in the `denops/@denops-private/worker.ts` file.
rg 'host.call' denops/@denops-private/worker.ts

Length of output: 997

denops/@denops-private/testutil/shared_server.ts (2)

63-67: Ensure the modifications in the useSharedServer function are correct.

The modifications in the useSharedServer function include changes to the stdout and stderr streams. Verify that these modifications are correct and consistent with the existing logic.


<details>
<summary>Tools</summary>

<details>
<summary>GitHub Check: codecov/patch</summary><blockquote>

[warning] 67-67: denops/@denops-private/testutil/shared_server.ts#L67
Added line #L67 was not covered by tests

</blockquote></details>

</details>

---

`9-11`: **Ensure the new declarations are correct.**

The new declarations `origLog`, `origError`, and `noop` have been added. Verify that these declarations are correct and consistent with the existing logic.


Verification successful

The new declarations are correct.

The new declarations origLog, origError, and noop have been verified and are consistent with the existing logic in the file denops/@denops-private/testutil/shared_server.ts.

  • origLog found: const origLog = console.log.bind(console);
  • origError found: const origError = console.error.bind(console);
  • noop found: const noop = () => {};
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the new declarations in `denops/@denops-private/testutil/shared_server.ts`.

# Test: Search for the new declarations. Expect: Only occurances of the new declarations.
rg --type typescript $'const origLog = console.log.bind(console);\nconst origError = console.error.bind(console);\nconst noop = () => {};'

Length of output: 516



Script:

#!/bin/bash
# Description: Verify the new declarations in `denops/@denops-private/testutil/shared_server.ts`.

# Test: Search for the new declaration `origLog`. Expect: Occurrences of the declaration.
rg --type typescript 'const origLog = console.log.bind(console);'

# Test: Search for the new declaration `origError`. Expect: Occurrences of the declaration.
rg --type typescript 'const origError = console.error.bind(console);'

# Test: Search for the new declaration `noop`. Expect: Occurrences of the declaration.
rg --type typescript 'const noop = () => {};'

Length of output: 382



Script:

#!/bin/bash
# Description: Verify the new declarations in `denops/@denops-private/testutil/shared_server.ts`.

# Test: Search for the new declaration `origLog`. Expect: Occurrences of the declaration.
rg 'const origLog = console.log.bind(console);'

# Test: Search for the new declaration `origError`. Expect: Occurrences of the declaration.
rg 'const origError = console.error.bind(console);'

# Test: Search for the new declaration `noop`. Expect: Occurrences of the declaration.
rg 'const noop = () => {};'

Length of output: 258



Script:

#!/bin/bash
# Description: Verify the new declarations in `denops/@denops-private/testutil/shared_server.ts`.

# Test: Search for the new declaration `origLog`. Expect: Occurrences of the declaration.
rg 'const origLog = console.log.bind(console);' denops/@denops-private/testutil/shared_server.ts

# Test: Search for the new declaration `origError`. Expect: Occurrences of the declaration.
rg 'const origError = console.error.bind(console);' denops/@denops-private/testutil/shared_server.ts

# Test: Search for the new declaration `noop`. Expect: Occurrences of the declaration.
rg 'const noop = () => {};' denops/@denops-private/testutil/shared_server.ts

Length of output: 405



Script:

#!/bin/bash
# Description: Verify the new declarations in `denops/@denops-private/testutil/shared_server.ts`.

# Test: Search for the new declaration `origLog`. Expect: Occurrences of the declaration.
rg 'const origLog =' denops/@denops-private/testutil/shared_server.ts

# Test: Search for the new declaration `origError`. Expect: Occurrences of the declaration.
rg 'const origError =' denops/@denops-private/testutil/shared_server.ts

# Test: Search for the new declaration `noop`. Expect: Occurrences of the declaration.
rg 'const noop =' denops/@denops-private/testutil/shared_server.ts

Length of output: 327

denops/@denops-private/testutil/shared_server_test.ts (7)

4-4: Import statement looks good.

The assertNotMatch function is correctly imported for use in the new test cases.


8-8: Import statement looks good.

The join function is correctly imported for use in the new test cases.


12-27: New test cases for useSharedServer function look good.

The test cases cover scenarios where the verbose option is not specified, ensuring that the addr and stdout are correctly returned and that stdout is not output.


29-43: New test cases for useSharedServer function look good.

The test cases cover scenarios where the verbose option is set to true, ensuring that the addr and stdout are correctly returned and that stdout is output.


47-61: New test cases for useSharedServer function look good.

The test cases cover scenarios where the verbose option is set to true, ensuring that the addr and stdout are correctly returned and that stdout is output.


63-77: New test cases for useSharedServer function look good.

The test cases cover scenarios where the verbose option is set to true, ensuring that the addr and stdout are correctly returned and that stdout is output.


Line range hint 111-124: New test cases for close method look good.

The test cases ensure that the close method is correctly called and handles invalid arguments appropriately.

denops/@denops-private/host_test.ts (2)

18-18: New method close added to the service object looks good.

The close method is correctly added to the service object and is unimplemented for testing purposes.


111-124: New test cases for close method look good.

The test cases ensure that the close method is correctly called and handles invalid arguments appropriately.

denops/@denops-private/host/vim_test.ts (1)

17-25: New method close added to the service object looks good.

The close method is correctly added to the service object and is unimplemented for testing purposes.

denops/@denops-private/testutil/with.ts (10)

1-9: New import statements and constants look good.

The channel, tap, origLog, origError, and noop are correctly imported and defined for use in the functions.


11-16: New type definition for Fn looks good.

The Fn type now includes stdout and stderr streams, which are necessary for the new functionality.


58-59: New command for setting columns looks good.

The command ensures that the output does not wrap unexpectedly.


85-86: New command for setting columns looks good.

The command ensures that the output does not wrap unexpectedly.


97-103: New listener setup looks good.

The listener is correctly set up to accept connections on a free port.


107-113: New environment variables look good.

The environment variables are correctly set up to include the address of the listener.


117-122: New stream handling looks good.

The stdout and stderr streams are correctly piped through the TextDecoderStream and tap functions if verbose mode is enabled.

Tools
GitHub Check: codecov/patch

[warning] 120-122: denops/@denops-private/testutil/with.ts#L120-L122
Added lines #L120 - L122 were not covered by tests


123-127: New channel setup for stdout and stderr looks good.

The channels are correctly set up to handle the stdout and stderr streams.


130-135: New function parameters look good.

The function now includes stdout and stderr streams in the parameters.


138-149: New process cleanup looks good.

The process cleanup code correctly handles the stdout and stderr streams.

Tools
GitHub Check: codecov/patch

[warning] 141-142: denops/@denops-private/testutil/with.ts#L141-L142
Added lines #L141 - L142 were not covered by tests

denops/@denops-private/host/nvim_test.ts (1)

22-22: LGTM!

The destructuring of fn function parameters improves readability and the addition of the close method aligns with the new functionality.

autoload/denops/_internal/server/chan.vim (6)

72-85: LGTM!

The timeout and force close logic are appropriate and well-implemented.


114-116: LGTM!

The initialization of s:chan is appropriate and well-implemented.


121-131: LGTM!

The force close logic and debug logging are appropriate and well-implemented.


133-138: LGTM!

The logic to clear the force close delayer is appropriate and well-implemented.


140-154: LGTM!

The close event handling and reconnection logic are appropriate and well-implemented.


31-31: LGTM!

The introduction of the l:i variable for retry attempts is appropriate.

Verification successful

LGTM!

The introduction of the l:i variable for retry attempts is appropriate. The function denops#_internal#server#chan#connect is used correctly in the following locations:

  • autoload/denops/server.vim
  • autoload/denops/_internal/server/chan.vim
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of the function `denops#_internal#server#chan#connect`.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type vim $'denops#_internal#server#chan#connect'

Length of output: 370

autoload/denops/server.vim (8)

22-36: LGTM!

The status checks and logging are appropriate and well-implemented.


48-59: LGTM!

The status checks and logging are appropriate and well-implemented.


67-67: LGTM!

The asynchronous restart logic is appropriate and well-implemented.


67-69: LGTM!

The force stop logic is appropriate and well-implemented.


77-94: LGTM!

The status checks and logging are appropriate and well-implemented.


98-102: LGTM!

The status checks and logging are appropriate and well-implemented.


110-110: LGTM!

The asynchronous reconnection logic is appropriate and well-implemented.


122-128: LGTM!

The new states closing and closed are appropriate and well-implemented.

doc/denops.txt (2)

157-161: LGTM!

The new variable g:denops#server#close_timeout has been added with appropriate description.


307-308: LGTM!

The new status closing and closed added to the function denops#server#status are appropriate and well-written.

denops/@denops-private/worker_test.ts (2)

Line range hint 209-237: Ensure proper synchronization and error handling with doautocmd execution.

The doautocmd command execution looks correct, but ensure that any asynchronous operations depending on this are properly synchronized and error-handled to avoid race conditions.

Verification successful

Ensure proper synchronization and error handling with doautocmd execution.

The functions using doautocmd are invoked within an asynchronous context using autocmd with the ++nested flag, and proper error handling is implemented using try-finally blocks.

  • autoload/denops/server.vim
  • autoload/denops/_internal/plugin.vim
  • autoload/denops/_internal/server/chan.vim

These findings confirm that proper synchronization and error handling are in place for doautocmd execution.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify proper synchronization and error handling with `doautocmd` execution.

# Test: Search for `doautocmd` usage. Expect: Proper synchronization and error handling.
rg --type vimscript $'doautocmd'

Length of output: 1131



Script:

#!/bin/bash
# Description: Extract surrounding code for each `doautocmd` usage to inspect synchronization and error handling mechanisms.

# Extract 10 lines before and after each `doautocmd` usage for context.
rg --type vimscript --context 10 'doautocmd'

Length of output: 12442



Script:

#!/bin/bash
# Description: Search for function calls where `doautocmd` is used to inspect synchronization.

# Search for function definitions containing `doautocmd` to get function names.
functions=$(rg --type vimscript --context 0 'doautocmd' | rg --type vimscript --context 10 'function!' | awk '/function!/ {print $2}')

# Search for function calls for each function containing `doautocmd`.
for func in $functions; do
  echo "Searching for calls to function: $func"
  rg --type vimscript "\b$func\b"
done

Length of output: 137



Script:

#!/bin/bash
# Description: Refine search for function calls where `doautocmd` is used to inspect synchronization.

# Search for function definitions containing `doautocmd` to get function names.
functions=$(rg --type vimscript --context 10 'doautocmd' | rg --type vimscript --context 10 'function!' | awk '/function!/ {print $2}')

# Search for function calls for each function containing `doautocmd`.
for func in $functions; do
  echo "Searching for calls to function: $func"
  rg --type vimscript "\b$func\b"
done

Length of output: 4759


Line range hint 458-471: Ensure correct handling of SIGINT signal.

The handling of the SIGINT signal should be verified to ensure that it properly disposes of resources and cleans up as expected.

tests/denops/server_test.ts (4)

119-310: Verify the correctness of denops#server#start() tests.

The tests for denops#server#start() should be verified to ensure they accurately cover all scenarios, including edge cases and error handling.

Verification successful

Verification of denops#server#start() tests:

The tests for denops#server#start() appear to be comprehensive, covering various scenarios, including edge cases and error handling.

  • Instances found in tests/denops/server_test.ts confirm the presence and likely comprehensiveness of the tests.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#start()` tests.

# Test: Search for `denops#server#start` tests. Expect: Comprehensive coverage of all scenarios, including edge cases and error handling.
rg --type typescript $'denops#server#start'

Length of output: 77



Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#start()` tests.

# Test: Search for `denops#server#start` tests. Expect: Comprehensive coverage of all scenarios, including edge cases and error handling.
rg --type ts $'denops#server#start'

Length of output: 1137


313-441: Verify the correctness of denops#server#stop() tests.

The tests for denops#server#stop() should be verified to ensure they accurately cover all scenarios, including edge cases and error handling.

Verification successful

Verified the correctness of denops#server#stop() tests.

The tests for denops#server#stop() in tests/denops/server_test.ts comprehensively cover various scenarios, including edge cases and error handling.

  • tests/denops/server_test.ts: Multiple instances of denops#server#stop calls.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#stop()` tests.

# Test: Search for `denops#server#stop` tests. Expect: Comprehensive coverage of all scenarios, including edge cases and error handling.
rg --type typescript $'denops#server#stop'

Length of output: 76



Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#stop()` tests.

# Test: Search for `denops#server#stop` tests. Expect: Comprehensive coverage of all scenarios, including edge cases and error handling.
rg 'denops#server#stop'

Length of output: 1092


Line range hint 18-111: Verify the correctness of denops#server#status() tests.

The tests for denops#server#status() should be verified to ensure they accurately cover all possible states and transitions.

Verification successful

Verified: The tests for denops#server#status() cover all possible states and transitions comprehensively.

  • The search results show multiple instances of denops#server#status within the tests/denops/server_test.ts file, indicating thorough testing of various server states and transitions.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#status()` tests.

# Test: Search for `denops#server#status` tests. Expect: Comprehensive coverage of all states and transitions.
rg --type typescript $'denops#server#status'

Length of output: 78



Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#status()` tests.

# Test: Search for `denops#server#status` tests within TypeScript files.
rg 'denops#server#status' --glob '*.ts'

Length of output: 6388


443-937: Verify the correctness of denops#server#connect() and denops#server#close() tests.

The tests for denops#server#connect() and denops#server#close() should be verified to ensure they accurately cover all scenarios, including edge cases and error handling.

Verification successful

Let's re-run the search without specifying the file type to ensure we capture all relevant instances of denops#server#connect and denops#server#close.


Tests for denops#server#connect() and denops#server#close() are present and cover various scenarios.

The search results confirm that the tests for denops#server#connect() and denops#server#close() are present in the tests/denops/server_test.ts file and cover various scenarios, including edge cases and error handling.

  • tests/denops/server_test.ts: Multiple references to denops#server#connect
  • tests/denops/server_test.ts: Multiple references to denops#server#close
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#connect()` and `denops#server#close()` tests.

# Test: Search for `denops#server#connect` and `denops#server#close` tests. Expect: Comprehensive coverage of all scenarios, including edge cases and error handling.
rg --type typescript $'denops#server#connect'
rg --type typescript $'denops#server#close'

Length of output: 157



Script:

#!/bin/bash
# Description: Verify the correctness of `denops#server#connect()` and `denops#server#close()` tests.

# Test: Search for `denops#server#connect` and `denops#server#close` tests.
rg 'denops#server#connect'
rg 'denops#server#close'

Length of output: 2853

Comment on lines +1 to +15
import {
assert,
assertEquals,
assertFalse,
assertMatch,
assertRejects,
} from "jsr:@std/[email protected]";
import { delay } from "jsr:@std/async@^0.224.0/delay";
import { AsyncDisposableStack } from "jsr:@nick/[email protected]/async-disposable-stack";
import { testHost } from "../../denops/@denops-private/testutil/host.ts";
import { useSharedServer } from "../../denops/@denops-private/testutil/shared_server.ts";
import { wait } from "../../denops/@denops-private/testutil/wait.ts";

const MESSAGE_DELAY = 200;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistency in import statements.

The import statements should be consistent in terms of formatting and order. Consider grouping similar imports together and separating them with a blank line for better readability.

import {
  assert,
  assertEquals,
  assertFalse,
  assertMatch,
  assertRejects,
} from "jsr:@std/[email protected]";
import { delay } from "jsr:@std/async@^0.224.0/delay";
import { AsyncDisposableStack } from "jsr:@nick/[email protected]/async-disposable-stack";
import { testHost } from "../../denops/@denops-private/testutil/host.ts";
import { useSharedServer } from "../../denops/@denops-private/testutil/shared_server.ts";
import { wait } from "../../denops/@denops-private/testutil/wait.ts";

const MESSAGE_DELAY = 200;

Committable suggestion was skipped due to low confidence.

Copy link
Member

@lambdalisue lambdalisue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -58,24 +57,23 @@ else
\ 'err_cb': funcref('s:out_cb', [a:options.on_stderr, 'stderr']),
\ 'exit_cb': funcref('s:exit_cb', [a:options.on_exit, 'exit']),
\}
return job_start(a:args, l:options)
let l:job = job_start(a:args, l:options)
if l:job->job_status() !=# "run"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 I didn't realized but Neovim supports method syntax from Neovim 0.6.0

neovim/neovim@003c8ac

@lambdalisue
Copy link
Member

lambdalisue commented Jun 30, 2024

@Milly It seems the status is still draft. Let me know when the PR become ready (I already reviewed in case)

and after review I want to amend it to 👍 change denops#server#start and ...#stop to asynchronous because it breaks tests.

Got it. Let me know when rebased @Milly

Milly added 2 commits July 1, 2024 09:46
- Add new `denops-variable`:
  - `g:denops#server#close_timeout`
- Add new state for `denops#server#status()`:
  - `closing`
  - `closed`
- Change behavior `denops-function`:
  - `denops#server#start()` can now be called even when status is
    `closing`. In that case, the status will become `stopped` and then
    restart asynchronously.
  - `denops#server#stop()` is changed to asynchronously. It waits for
    the server to close gracefully, and force terminate if timeouted.
  - `denops#server#restart()` is changed to asynchronously. Perform the
    stop and start steps above.
@Milly Milly force-pushed the async-server-start-stop branch from 5e7e3c2 to f766e94 Compare July 1, 2024 00:47
@Milly Milly marked this pull request as ready for review July 1, 2024 00:56
@Milly
Copy link
Contributor Author

Milly commented Jul 1, 2024

I rebased it. @lambdalisue

@lambdalisue lambdalisue merged commit 97ed0ff into v7-pre Jul 1, 2024
7 of 9 checks passed
@lambdalisue lambdalisue deleted the async-server-start-stop branch July 1, 2024 08:14
@coderabbitai coderabbitai bot mentioned this pull request Aug 2, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants