Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XDG_RUNTIME_DIR environment variable to choose the path used for the creation of sockets #6887

Merged
merged 8 commits into from May 27, 2022

Conversation

AlonsoM45
Copy link
Contributor

@AlonsoM45 AlonsoM45 commented Apr 26, 2022

The XDG_RUNTIME_DIR environment variable will be used to choose the base directory in which the sockets will be created by sbt. This can help when issues such as #6777 appear. There are other related issues, such as #6101, Metals issue #2235, Che issue #18394. Those are closed issues, but there are some cases in which the solution does not work (such as the case in #6777). Furthermore, the solution given seems more like a workaround than an actual fix.

What causes this issue?
At least in my case, the ServerAlreadyBootingException is thrown after sbt tries to create a Unix domain socket and fails. In my specific environment, I was not able to create the sockets in some directories because they were mounted on an NFS. This prevented me from using any automated sbt command on any of those directories (Metals uses sbt under the hood, and it was not able to start because of the ServerAlreadyBootingException), which in turn resulted in me not being able to use Metals on a project that was created on any of those directories.

How is the issue solved in this PR?
If the XDG_RUNTIME_DIR environment variable is set, then sockets will be created in a folder with a hashed name, inside the directory XDG_RUNTIME_DIR/.sbt/. If this variable is not set, everything works exactly the same as always.

Let's see an example:

  1. My environment variable XDG_RUNTIME_DIR is set to /home/alonso/.runtime-dir`
  2. I create my project in /home/alonso/workspace/hello-world
  3. I run sbt compile
  4. The socket is created in /home/alonso/.runtime-dir/.sbt/sbt-socket102030405060/sbt-load.sock. The number 102030405060 is a hash that is computed from the base directory of the project (it is actually the same hash that is produced in order to create sockets in Windows) and it will be different depending on the location of the project
  5. The sbt command executed correctly, which would not have happened if the socket had been created in the home/alonso/workspace directory or any of its subdirectories (in this example, /home/BlackDiamond/workspace corresponds to a network file share)

@lightbend-cla-validator

Hi @AlonsoMontero, @AlonsoM45,

Thank you for your contribution! We really value the time you've taken to put this together.

Before we proceed with reviewing this pull request, please sign the Lightbend Contributors License Agreement:

https://www.lightbend.com/contribute/cla

@eed3si9n
Copy link
Member

eed3si9n commented May 1, 2022

Thanks for the contribution.

Rather than creating a system property for this specific use case, I wonder if we should use this as an opportunity to adhere to some existing standards like XDG Base Directory Specification (#3681). For instance, I think it recommends socket files to be created under XDG_RUNTIME_DIR somewhere. We can respect the environment variable, which you can set to whatever, and also move the default of that to something like /tmp/.sbt/.

What do you think?

@AlonsoM45
Copy link
Contributor Author

AlonsoM45 commented May 4, 2022

Hello, I changed the code in order to use the XDG_RUNTIME_DIR environment variable whenever we are not using Windows. The default of that variable will be /tmp, and then the sockets will be created in the directory XDG_RUNTIME_DIR/.sbt. How does it look to you?

@eed3si9n
Copy link
Member

eed3si9n commented May 7, 2022

Yea. Mostly looks good I think. Could you update the description of the PR to reflect the update please?

@AlonsoM45 AlonsoM45 changed the title Add option -Dsbt.altSockLocation, which allows the user to specify a directory in which the Unix Domain Sockets for the projects will be created Use XDG_RUNTIME_DIR environment variable to choose the path used for the creation of sockets May 8, 2022
@AlonsoM45
Copy link
Contributor Author

Yea. Mostly looks good I think. Could you update the description of the PR to reflect the update please?

Done, I have just updated it.

@eed3si9n eed3si9n merged commit 86fd6dc into sbt:develop May 27, 2022
@AlonsoM45
Copy link
Contributor Author

Thanks @eed3si9n for your review, your suggestions and for merging this PR. I had a question for you, if you don't mind: Do you have an estimated date for the next release?

@AlonsoM45 AlonsoM45 deleted the fix/6777 branch May 27, 2022 13:24
@eed3si9n
Copy link
Member

@AlonsoM45 It's a bit concerning that the develop branch is no longer passing on CI though. I don't know if this is caused by merging this PR.

@eed3si9n
Copy link
Member

develop branch is slated for sbt 2.x, so for this to see the day of light sooner we need to backport this to 1.7.x and/or 1.6.x branch.

eed3si9n pushed a commit to eed3si9n/sbt that referenced this pull request May 29, 2022
…the creation of sockets (sbt#6887)

The `XDG_RUNTIME_DIR` environment variable will be used to choose the base directory in which the sockets will be created by **sbt**. This can help when issues such as sbt#6777 appear. There are other related issues, such as sbt#6101, [Metals issue sbt#2235](scalameta/metals#2235), [Che issue #18394](eclipse-che/che#18394). Those are closed issues, but there are some cases in which the solution does not work (such as the case in sbt#6777). Furthermore, the solution given seems more like a workaround than an actual fix.

**What causes this issue?**
At least in my case, the **ServerAlreadyBootingException** is thrown after **sbt** tries to create a Unix domain socket and fails. In my specific environment, I was not able to create the sockets in some directories because they were mounted on an NFS. This prevented me from using any automated sbt command on any of those directories (Metals uses sbt under the hood, and it was not able to start because of the ServerAlreadyBootingException), which in turn resulted in me not being able to use Metals on a project that was created on any of those directories. 

**How is the issue solved in this PR?**
If the `XDG_RUNTIME_DIR` environment variable is set, then sockets will be created in a folder with a hashed name, inside the directory `XDG_RUNTIME_DIR/.sbt/`. If this variable is not set, everything works exactly the same as always.

Let's see an example:

1. My environment variable `XDG_RUNTIME_DIR` is set to /home/alonso/.runtime-dir`
2. I create my project in `/home/alonso/workspace/hello-world`
3. I run `sbt compile`
4. The socket is created in `/home/alonso/.runtime-dir/.sbt/sbt-socket102030405060/sbt-load.sock`. The number **102030405060** is a hash that is computed from the base directory of the project (it is actually the same hash that is produced in order to create sockets in Windows) and it will be different depending on the location of the project
5. The sbt command executed correctly, which would not have happened if the socket had been created in the `home/alonso/workspace` directory or any of its subdirectories (in this example, `/home/BlackDiamond/workspace` corresponds to a network file share)

Co-authored-by: Alonso Montero <lumontero@mobilize.net>
@eed3si9n
Copy link
Member

#6907 tested and merged.

@eed3si9n eed3si9n added this to the 1.7.0 milestone May 29, 2022
@AlonsoM45
Copy link
Contributor Author

Hello. I saw that CI is passing now. I assume everything is OK now on that side. Thanks for backporting this to 1.7.x.

@Jasper-M
Copy link

Jasper-M commented Sep 2, 2022

One possible issue with defaulting to /tmp here is that it's shared between all users, and if one user creates /tmp/.sbt/sbt-socketXXXXXX then another might not have appropriate permissions on /tmp/.sbt or /tmp/.sbt/sbt-socketXXXXXX. And that's without considering concurrent users.

@bishabosha
Copy link

bishabosha commented Jan 11, 2023

This change seems to negatively effect macOS where for some reason if XDG_RUNTIME_DIR does not exist then now sbt tries to make a socket from a temp directory, which has a path too long to make a socket from.

Edit: the problem in macOS was caused by #6935 which sets the default directory to be a temp directory - which is too long for a unix socket on macOS

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

Successfully merging this pull request may close these issues.

None yet

6 participants