tern_for_vim icon indicating copy to clipboard operation
tern_for_vim copied to clipboard

delays when switching windows

Open clausreinke opened this issue 11 years ago • 19 comments

I don't have a reproducible case yet - posting as a reminder: sometimes switching windows is delayed. Last time I saw this, I suspected the logic in tern_sendBufferIfDirty, because it kept happening for freshly opened, unmodified source.

clausreinke avatar Jul 02 '13 08:07 clausreinke

I too experience this, and also weird delays in other parts of moving around vim. I want to see if it's related to https://github.com/marijnh/tern_for_vim/issues/27, because when a bunch of node procs stay open, vim eventually just locks up, even though they don't use much cpu.

AndrewRayCode avatar Jul 02 '13 20:07 AndrewRayCode

@DelvarWorld have you perhaps set g:tern_show_argument_hints to 'on_move'? That tends to make movements sluggish, and is different from the issue here.

clausreinke avatar Jul 02 '13 23:07 clausreinke

It's set to 'on_hold' for me

AndrewRayCode avatar Jul 02 '13 23:07 AndrewRayCode

It is now at the point where it's just completely unusable.

I have no idea what's going on, but when I open my process manager and start moving around in vim, I can see node processes spawned every time I make a move.

This plugin is definitely not ready for prime time.

AndrewRayCode avatar Jul 03 '13 22:07 AndrewRayCode

back to my original suspicion. 1.add a trace line to tern_sendBuffer, something like: vim.command("echo 'tern_sendBuffer ' b:ternBufferSentAt") 2.split edit two .js files and keep switching between the two. 3. buffer will keep being sent thought no edits have taken place Also, if tern hasn't been started yet, it shouldn't be started on switching away from a buffer.

clausreinke avatar Jul 11 '13 09:07 clausreinke

further tracing shows this to be related to old .tern-port files (which normally do not get cleared away on windows). Here's my traced code

def tern_sendBuffer(files=None):
  vim.command("echo 'tern_sendBuffer ' b:ternBufferSentAt")
  port, _portIsOld = tern_findServer()
  if port is None: return False
  try:
    vim.command("echo 'tern_sendBuffer (server found)' "+str(port))
    tern_makeRequest(port, {"files": files or [tern_fullBuffer()]})
    vim.command("echo 'tern_sendBuffer (true)' ")
    return True
  except Exception as e:
    vim.command("echo 'tern_sendBuffer (except)' "+json.dumps(str(e)))
    return False

if tern_findServer finds an old port, tern_makeRequest will use that and time out, so tern_sendBuffer returns False, so tern_sendBufferIfDirty never updates b:ternBufferSentAt. The game repeats next time, always waiting for the time outs.

clausreinke avatar Jul 11 '13 15:07 clausreinke

If no tern has been started and the buffer has not been modified, no action should be taken. Determining the former might take some refactoring.

clausreinke avatar Sep 19 '13 16:09 clausreinke

Is there some way for me to determine if I'm having this issue, and is there a solution to this problem? I've tried Tern for Vim for the first time today, I'm impressed with the completions it can give me, but opening files and switching between splits consistently takes around 2 seconds, which gets annoying really fast.

FrigoEU avatar Jul 15 '14 10:07 FrigoEU

Are these files huge? Tern fires off an HTTP request to update the Tern server on the file's content when you leave a buffer that was changed. Due to Vim's primitive API, it does this synchronously. Since the server is on a local loopback device, this should not take 2 seconds, though!

marijnh avatar Jul 15 '14 10:07 marijnh

For me, this wasn't a file size issue, just a problem with the try/timeout logic - see the tracing suggestions above. The delays were caused by tern autocmds firing on switch, then finding an old .tern-port file, then timing out when trying to connect to the non-existing server, then starting a new server and trying again. Without any explicit tern action having been requested..

I'm not sure what happened to the autocmd aspect, but since the termination changes for windows, the old .tern-port files no longer hang around for me, which has improved the situation a lot.

clausreinke avatar Jul 15 '14 10:07 clausreinke

Nope they are small files, ranging from 50 to max 200 lines of code. Eg: just made a new spec file, consisted of 5 lines of code. Went to my other split: 1 second delay. Added a comment in the spec file, still 5 lines, again 1 second delay. My PC is running on 6 GB Ram, i7 processor, Windows 8.1.

On a related note: What's the response time on the autocompletion itself I can expect? Right now I also have to wait between 1-2 seconds to get a response. That's pretty acceptable to me, but just wondering.

With the risk of being called a total Vim noob: I can't really make sense of the tracing suggestions of clausreinke. Where exactly should I be adding these? Or, where can I find these .tern-port files?

Some extra info: This is the .tern-project file I'm using: { "libs": [ "browser", "ecma5", "underscore" ], "plugins": { "angular":{} }, "dontload": [ "node_modules/", "app/bower_components/", "dev_", "dist_" ] }

Would really like to get this working silky-smooth since the autocompletion is pretty amazing.

FrigoEU avatar Jul 15 '14 11:07 FrigoEU

tern_for_vim no longer creates .tern-port files by default (they are a way for tern servers to announce how they can be reached; without them, vim just starts a new server).

So unless you've got an old .tern-port file in your source tree, or you have overridden g:tern#command in your vimrc (missing the --no-port-file option to tern), or are using an older version of tern_for_vim, you are probably not suffering from the original issue. Since the symptoms sound almost identical, it is worth checking.

The tracing suggestions were just my way of adding "print" statements for debugging the issue - the code is likely to have changed somewhat since then (in autoload/tern.vim and script/tern.py). Basically, I was staring at the code until I had a suspect, then adding vim.command("echo <some useful info>") statements to confirm my suspicions.

The issue was that tern_for_vim was trying to send commands to a non-existing server, and had to wait for the attempt to time out before proceeding, once for every buffer switch.

Completions can take a while the first time round, as that starts the tern background process and processes the source files in question. After that, completions tend to be quick.

clausreinke avatar Jul 15 '14 22:07 clausreinke

Just as an update: I'm switching my development environment to Linux, where Tern does seem to work without delays!

FrigoEU avatar Jul 22 '14 06:07 FrigoEU

Sorry to thread-necro, but I'm experiencing the same issue as @FrigoEU (1-2 second delays on file switching) when using Vim 7.4 in cmder on Win8.1.

I also use tern for vim on linux without issue, but am sometimes forced to use a windows machine and would love to get tern working without these annoying delays. Does anyone have a solution?

jamiecollinson avatar Apr 23 '15 12:04 jamiecollinson

same issue, running on osx, very small files, delay has been upwards of a minute at times, and I have not been able to quit vim, oh and I set hint argument "on_hold". When I run top, I can see that whenever I change buffers or execute a tern command( ex. <Leader> tr ) a new node task is created for each buffer and each tern command, and the task does not end until I eventually have to force quit vim(console). When I remove tern( I am using pathogen ) everything goes back to normal. May try and grab an older version, have used tern for vim for about a year now on my own machine and love it, but setting up the current machine I am on for work, I am kind of at a loss. Will try and look into hacking something together in the mean time. Will report back with/if any success.

corymickelson avatar May 02 '15 23:05 corymickelson

I still can't figure out where this is coming from -- but then, I don't have much experience with vim. Further diagnostic information definitely welcome.

marijnh avatar May 27 '15 09:05 marijnh

I get the delay when tern server shuts itself down after five minutes of inactivity. Logic in tern_sendBufferIfDirty() tries to connect to nonexistent tern server. Delay goes away when I trigger completion which starts new tern server.

As a workaround to fix this issue I use let g:tern#arguments = ["--persistent"].

markonm avatar Mar 14 '17 23:03 markonm

The code is supposed to immediately notice when it tries to talk to a server that's gone (the connection attempt will produce a 'connection refused' error) and start a new one. Are you running some kind of firewall or similar that might be intercepting and blocking connections to unused ports?

marijnh avatar Mar 15 '17 09:03 marijnh

I use default Windows firewall. It also doesn't help if I turn it off. I added this to make it start new server if old one is missing on BufLeave event.

diff --git a/script/tern.py b/script/tern.py
index 49e29f4..498c50f 100644
--- a/script/tern.py
+++ b/script/tern.py
@@ -235,7 +235,12 @@ def tern_sendBuffer(files=None):
     tern_makeRequest(port, {"files": files or [tern_fullBuffer()]}, True)
     return True
   except:
-    return False
+    try:
+      port, _portIsOld = tern_findServer(port)
+      tern_makeRequest(port, {"files": files or [tern_fullBuffer()]}, True)
+      return True
+    except:
+      return False
 
 def tern_sendBufferIfDirty():
   if (vim.eval("exists('b:ternInsertActive')") == "1" and

With this change I only get delay on first BufLeave event.

Similar check is made in tern_runCommand function, which does start new server if old one is missing.

markonm avatar Mar 15 '17 15:03 markonm