atom-languageclient icon indicating copy to clipboard operation
atom-languageclient copied to clipboard

Keep server alive for a project

Open laughedelic opened this issue 7 years ago • 7 comments

In Scala projects it makes sense to keep language server alive for the whole project, because the startup is quite slow.

Currently, server is started only when I open a Scala source, then every time I close the last tab with Scala source, server is stopped and if I open a new tab, new server is started again.

I'd like to implement a workflow where server is started when I open a new project (in Atom terminology) which looks like a Scala project (checking sbt or ENSIME configuration files presence), then stop it only when the project is removed from the workspace.

I thought at first, that this method could be helpful:

https://github.com/atom/atom-languageclient/blob/1153b29f94ab0c7ff588445ac1ac6622460d124b/lib/auto-languageclient.js#L75-L76

But this is about adding condition on an editor, not workspace or project. I also see that server is considered unused and is stopped when all associated editors are closed in

https://github.com/atom/atom-languageclient/blob/1153b29f94ab0c7ff588445ac1ac6622460d124b/lib/server-manager.js#L158

But I don't know how to override this behavior for my client. Is it possible to do? And if not, would it be viable to support such workflow?

laughedelic avatar Nov 11 '17 00:11 laughedelic

:+1: Ensime server requires some time to start, so it's quite important not to relaunch it.

vovapolu avatar Nov 21 '17 15:11 vovapolu

Hi, I've been toying with a language server for a couple of days and I wanted a similar configuration. I have something that works-ish, so I'll share it in case it's useful.

  1. The server is started and stopped independently; it has to be running for atom-languageclient to work.
  2. In my AutoLanguageClient, I use startServerProcess to spawn a process using another JS file, much like the example:
startServerProcess () {
  const scriptPath =  require.resolve('my-client/lib/client_process.js')
  return super.spawnChildNode([scriptPath])
}
  1. In client_process.js, I open a socket connection to the already-running language server. I pipe the process's STDIN and STDOUT to the socket, so that the client process is a basically pipe between Atom and the language server.
  2. The client process also handles disconnects & reconnects, so that I can restart the server without crashing Atom.

I have a few outstanding issues:

  • It seems like I should be able to use the socket connection type from this library, but I couldn't get it to work right with reconnections.
  • I'd like to improve the experience when the language server is not running. Right now, it's just silent.
  • I'd like to improve startServerProcess to handle connection failure by re-starting the language server, but I haven't done that yet, so you have to start the server separately.

I'm a bit out of my depth on this, but if you have any feedback, I'd love to hear it, or if you're interested, I can try to share some code!

rmosolgo avatar Nov 21 '17 18:11 rmosolgo

I think this is tied up with https://github.com/atom/atom-languageclient/issues/71 and the various connection problems.

My plan is to make the servers restartable from code and to provide an easy way for ide-x authors to specify how long to idle before shutting them down (or opt out entirely to do it themselves).

Hoping to begin working on this tomorrow as well as having auto-restarting on connection/server failure.

damieng avatar Nov 22 '17 06:11 damieng

My plan is to make the servers restartable from code and to provide an easy way for ide-x authors to specify how long to idle before shutting them down (or opt out entirely to do it themselves).

@damieng although this functionality is useful on its own, I don't see how it addresses the described use-case for server lifecycle tied to projects. It requires altering current logic of stopUnusedServers: instead of tracking whether there are any editors bound to a server with _editorToServer map, it should track whether the project root folder is still open.

In the end, when you launch a language server, you do it for some notion of a "project" or "workspace" (rootUri in the initialization request). So I think that in general server lifecycle managed by server-manager should be more project-oriented instead of files/editors/tabs-oriented. I think that the latter works well only for scripting interpreted languages, which don't require any kind of project setup.

laughedelic avatar Nov 26 '17 04:11 laughedelic

So the possibilities as far as I see it are:

  • Always open on project open/add folder if a specific file is present (e.g. a project definition) and only close if Atom closes or the project folder is removed
  • Automatically shutdown last edited file but only after a delay (and if another file opens during that delay the stop never happens)
  • Custom logic to determine when to start and stop a server (what information would they need from atom-languageclient)

damieng avatar Dec 06 '17 04:12 damieng

Always open on project open/add folder if a specific file is present (e.g. a project definition) and only close if Atom closes or the project folder is removed

That's exactly what I wanted opening this issue. I would only make this predicate not too narrow, i.e. not just "specific file is present", but a general atom$Project => boolean. Similarly to the current:

https://github.com/atom/atom-languageclient/blob/f4c1ba242f6f9191b4ac1ce71258f49f61f877c3/lib/auto-languageclient.js#L81

But

shouldStartForProject(editor: atom$Project): boolean

Automatically shutdown last edited file but only after a delay (and if another file opens during that delay the stop never happens)

Independently of the previous alternative I see it useful for scripting languages (or markup languages) which don't need a project definition (i.e. server works with each source file independently).

laughedelic avatar Dec 06 '17 14:12 laughedelic

Development of atom-languageclient has officially moved to https://github.com/atom-ide-community/atom-languageclient 🎉

If this is still an issue please consider opening an issue on that repo.

UziTech avatar Oct 19 '20 19:10 UziTech