Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Keep server alive for a project #141

Open
laughedelic opened this issue Nov 11, 2017 · 7 comments
Open

Keep server alive for a project #141

laughedelic opened this issue Nov 11, 2017 · 7 comments

Comments

@laughedelic
Copy link
Contributor

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:

// Determine whether we should start a server for a given editor if we don't have one yet
shouldStartForEditor(editor: atom$TextEditor): boolean {

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

async stopUnusedServers(): Promise<void> {

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?

@vovapolu
Copy link

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

@rmosolgo
Copy link

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!

@damieng
Copy link
Contributor

damieng commented Nov 22, 2017

I think this is tied up with #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.

@laughedelic
Copy link
Contributor Author

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.

@damieng
Copy link
Contributor

damieng commented Dec 6, 2017

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)

@laughedelic
Copy link
Contributor Author

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:

shouldStartForEditor(editor: atom$TextEditor): boolean {

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).

@UziTech
Copy link

UziTech commented Oct 19, 2020

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants