Subject: bug#19636: [TRAMP] global minor mode hangs connection when accessing files in :lighter

From: Philippe Vaucher <[email-masked]>
Date: Sun, 25 Jan 2015 21:15:44 +0100

> > That's an interesting workaround, can I assume that
> > `default-directory` over a TRAMP connection is always absolute? what
> > about symlinks?
>
> You can always assume, that `default-directory' is absolute, being it
> local or remote. Symlinks are not expanded, 'tho.
>
> However, there is always the buffer local variable
> `buffer-file-truename'. Maybe you could use it somehow, when setting the
> lighter? Something like
>
> (if buffer-file-truename (file-name-directory buffer-file-truename) default-directory)

Thanks for mentionning `buffer-file-truename', I didn't know about it.
Unfortunately my problem is more complex than that because at the
moment this package does many files existence checks in order to find
the project root directory (e.g it tries to find any of "Gemfile",
".git", "Makefile" in the current directory, then if not found in the
parent one, etc). I know that all these filesystem checks doesn't
scale very well when not done locally, but I'm kinda stuck with the
current design. It is planned to refactor it all into leveraging
caching and possibly doing these checks by spawning a little bash
script remotely.

> Short analysis of the debug buffer:
(snip)
> Here Tramp opens a second connection in order to call git.
(snip)
> And here Tramp tries to use the primary connection for getting the
> truename of the default directory. Tramp is not able to accept those
> requests while preparing the second connection for
> start-file-process. Maybe I need to add something in order to make it
> more robust. This is not such easy, it might take time.

Ah, that's very helpful to understand what's going on. What is weird
is that there seems to be some kind of deadlocking happening, because
"git fetch" takes less than 10 seconds to finish, and in the log we
see that it just waits for 10 seconds until the "Are you awake"
message (I tried increasing the timeout but it just waits until the
timeout, not processing either the "git fetch" or the `file-truename'.
It seems that when the second connection starts, if you request
something that happens to use the first connection, the second
connection will also be stuck and nothing will happen until the
timeout is reached.

So, basically I can see 3 ways to tackle the problem:

- Don't try to do project detection when there's more than one TRAMP
connection to the same host. Can you point me at a way to do that?
Something like `(tramp-connections-count default-directory)'
- Find a way to detect wether the 2nd connection is "ready", which is
my attempt with `tramp-connectable-p' or `file-remote-p', but I
believe this way is a dead-end because TRAMP will tell me about the
1st connection and not the 2nd one.
- Fix TRAMP so it better handles multiple connections, but it's likely
to involve quite some work. Maybe a simple idea would be that calls to
`file-truename` always use the most recent connection? I'm not sure I
make sense so feel free to ignore it :)

Thank you!
Philippe