golang.org/x/tools/gopls@v0.15.3/doc/daemon.md (about)

     1  # Running gopls as a daemon
     2  
     3  **Note: this feature is new. If you encounter bugs, please [file an
     4  issue](troubleshooting.md#file-an-issue).**
     5  
     6  If you just want to try this out, skip ahead to the [quickstart](#quickstart).
     7  
     8  ## Background: gopls execution modes
     9  
    10  Gopls was originally implemented as an LSP sidecar: a process started by
    11  editors or editor plugins, and communicated with using jsonrpc 2.0 over
    12  stdin/stdout. By executing as a stateful process, gopls can maintain a
    13  significant amount of cache and can eagerly perform analysis on the source code
    14  being edited.
    15  
    16  This execution mode does not work as well when there are many separate editor
    17  processes or when editor processes are short-lived, as is often the case for
    18  users of non-IDE editors such as Vim or Emacs. Having many processes means
    19  having many caches, consuming a significant amount of system resources. Using
    20  short-lived sessions means paying a start-up cost each time a session is
    21  created.
    22  
    23  To support these types of workflows, a new mode of gopls execution is supported
    24  wherein a single, persistent, shared gopls "daemon" process is responsible for
    25  managing all gopls sessions. In this mode, editors still start a gopls sidecar,
    26  but this sidecar merely acts as a thin "forwarder", responsible for forwarding
    27  the LSP to the shared gopls instance and recording metrics, logs, and rpc
    28  traces.
    29  
    30  ## Quickstart
    31  
    32  To use a shared gopls instance you must either manage the daemon process
    33  yourself, or let the gopls forwarder processes start the shared daemon as
    34  needed.
    35  
    36  ### Running with `-remote=auto`
    37  
    38  Automatic management of the daemon is easiest, and can be done by passing the
    39  flag `-remote=auto` to the gopls process started by your editor. This will
    40  cause this process to auto-start the gopls daemon if needed, connect to it, and
    41  forward the LSP. For example, here is a reasonable gopls invocation, that sets
    42  some additional flags for easier [debugging](#debugging):
    43  
    44  ```bash
    45  gopls -remote=auto -logfile=auto -debug=:0 -remote.debug=:0 -rpc.trace
    46  ```
    47  
    48  Note that the shared gopls process will automatically shut down after one
    49  minute with no connected clients.
    50  
    51  ### Managing the daemon manually
    52  
    53  To manage the gopls daemon process via external means rather than having the
    54  forwarders manage it, you must start a gopls daemon process with the
    55  `-listen=<addr>` flag, and then pass `-remote=<addr>` to the gopls processes
    56  started by your editor.
    57  
    58  For example, to host the daemon on the TCP port `37374`, do:
    59  
    60  ```bash
    61  gopls -listen=:37374 -logfile=auto -debug=:0
    62  ```
    63  
    64  And then from the editor, run
    65  
    66  ```bash
    67  gopls -remote=:37374 -logfile=auto -debug=:0 -rpc.trace
    68  ```
    69  
    70  If you are on a POSIX system, you can also use unix domain sockets by prefixing
    71  the flag values with `unix;`. For example:
    72  
    73  ```bash
    74  gopls -listen="unix;/tmp/gopls-daemon-socket" -logfile=auto -debug=:0
    75  ```
    76  
    77  And connect via:
    78  
    79  ```bash
    80  gopls -remote="unix;/tmp/gopls-daemon-socket" -logfile=auto -debug=:0 -rpc.trace
    81  ```
    82  
    83  (Note that these flag values MUST be enclosed in quotes, because ';' is a
    84  special shell character. For this reason, this syntax is subject to change in
    85  the future.)
    86  
    87  ## Debugging
    88  
    89  Debugging a shared gopls session is more complicated than a singleton session,
    90  because there are now two gopls processes involved with handling the LSP. Here
    91  are some tips:
    92  
    93  ### Finding logfiles and debug addresses
    94  
    95  When running in daemon mode, you can use the `gopls inspect sessions` command
    96  to find the logfile and debug port for your gopls daemon instance (as well as
    97  for all its connected clients). By default, this inspects the default daemon
    98  (i.e. `-remote=auto`). To inspect a different daemon, use the `-remote` flag
    99  explicitly: `gopls -remote=localhost:12345 inspect sessions`.
   100  
   101  This works whether or not you have enabled `-remote.debug`.
   102  
   103  ### Traversing debug pages
   104  
   105  When `-debug=:0` is passed to gopls, it runs a webserver that serves stateful
   106  debug pages (see [troubleshooting.md](troubleshooting.md)). You can find the
   107  actual port hosting these pages by either using the `gopls inspect sessions`
   108  command, or by checking the start of the logfile -- it will be one of the first
   109  log messages. For example, if using `-logfile=auto`, find the debug address by
   110  checking `head /tmp/gopls-<pid>.log`.
   111  
   112  By default, the gopls daemon is not started with `-debug`. To enable it, set
   113  the `-remote.debug` flag on the forwarder instance, so that it invokes gopls
   114  with `-debug` when starting the daemon.
   115  
   116  The debug pages of the forwarder process will have a link to the debug pages of
   117  the daemon server process. Correspondingly, the debug pages of the daemon
   118  process will have a link to each of its clients.
   119  
   120  This can help you find metrics, traces, and log files for all of the various
   121  servers and clients.
   122  
   123  ### Using logfiles
   124  
   125  The gopls daemon is started with logging disabled by default. To customize
   126  this, pass `-remote.logfile` to the gopls forwarder. Using
   127  `-remote.logfile=auto`, the daemon will log to a default location (on posix
   128  systems: `/tmp/gopls-daemon-<pid>.log`).
   129  
   130  The gopls daemon does not log session-scoped messages: those are instead
   131  reflected back to the forwarder so that they can be accessed by the editor.
   132  Daemon logs will only contain global messages, for example logs when sessions
   133  connect and disconnect.
   134  
   135  It is recommended to start the forwarder gopls process with `-rpc.trace`, so
   136  that its logfile will contain rpc trace logs specific to the LSP session.
   137  
   138  ## Using multiple shared gopls instances
   139  
   140  There may be environments where it is desirable to have more than one shared
   141  gopls instance. If managing the daemon manually, this can be done by simply
   142  choosing different `-listen` addresses for each distinct daemon process.
   143  
   144  On POSIX systems, there is also support for automatic management of distinct
   145  shared gopls processes: distinct daemons can be selected by passing
   146  `-remote="auto;<id>"`. Any gopls forwarder passing the same value for `<id>`
   147  will use the same shared daemon.
   148  
   149  ## FAQ
   150  
   151  **Q: Why am I not saving as much memory as I expected when using a shared gopls?**
   152  
   153  A: As described in [implementation.md](design/implementation.md), gopls has a
   154  concept of view/session/cache. Each session and view map onto exactly one
   155  editor session (because they contain things like edited but unsaved buffers).
   156  The cache contains things that are independent of any editor session, and can
   157  therefore be shared.
   158  
   159  When, for example, three editor session are sharing a single gopls process,
   160  they will share the cache but will each have their own session and view. The
   161  memory savings in this mode, when compared to three separate gopls processes,
   162  corresponds to the amount of cache overlap across sessions.
   163  
   164  Because this hasn't mattered much in the past, it is likely that there is state
   165  that can be moved out of the session/view, and into the cache, thereby
   166  increasing the amount of memory savings in the shared mode.
   167  
   168  **Q: How do I customize the daemon instance when using `-remote=auto`?**
   169  
   170  The daemon may be customized using flags of the form `-remote.*` on the
   171  forwarder gopls. This causes the forwarder to invoke gopls with these settings
   172  when starting the daemon. As of writing, we expose the following configuration:
   173  
   174  * `-remote.logfile`: the location of the daemon logfile
   175  * `-remote.debug`: the daemon's debug address
   176  * `-remote.listen.timeout`: the amount of time the daemon should wait for new
   177    connections while there are no current connections, before shutting down.
   178    Must be set to a valid `time.Duration` (e.g. `30s` or `5m`). If `0`, listen
   179    indefinitely. Default: `1m`.
   180  
   181  Note that once the daemon is already running, setting these flags will not
   182  change its configuration. These flags only matter for the forwarder process
   183  that actually starts the daemon.