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

[WIP] Provide Support for Linux #36

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Conversation

RLovelett
Copy link
Owner

@RLovelett RLovelett commented Feb 2, 2018

Infraestructure

  • Update the build tools and CI

Code

Ogra Error Message

/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:95:128: warning: redundant same-type constraint 'Wrapped.Iterator.Element' == 'Wrapped.Element'
extension Optional where Wrapped: Collection & ExpressibleByArrayLiteral, Wrapped.Element: Encodable, Wrapped.Iterator.Element == Wrapped.Element {
                                                                                                                               ^
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:95:33: note: previous same-type constraint 'Wrapped.Element' == 'Wrapped.Iterator.Element' implied here
extension Optional where Wrapped: Collection & ExpressibleByArrayLiteral, Wrapped.Element: Encodable, Wrapped.Iterator.Element == Wrapped.Element {
                                ^
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:89:102: warning: redundant conformance constraint 'Self.Element': 'Encodable'
extension Collection where Self: ExpressibleByArrayLiteral, Self.Element: Encodable, Iterator.Element: Encodable {
                                                                                                     ^
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:89:73: note: conformance constraint 'Self.Element': 'Encodable' written here
extension Collection where Self: ExpressibleByArrayLiteral, Self.Element: Encodable, Iterator.Element: Encodable {
                                                                        ^
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:36:18: error: cannot convert value of type 'Int' to type 'NSNumber' in coercion
                return .number(self as NSNumber)
                               ^~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:42:18: error: cannot convert value of type 'Double' to type 'NSNumber' in coercion
                return .number(self as NSNumber)
                               ^~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:48:18: error: cannot convert value of type 'Float' to type 'NSNumber' in coercion
                return .number(self as NSNumber)
                               ^~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:54:18: error: cannot convert value of type 'UInt' to type 'NSNumber' in coercion
                return .number(self as NSNumber)
                               ^~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:109:29: error: cannot convert value of type 'Int' to type 'NSNumber' in coercion
        return .number(self.rawValue as NSNumber)
                       ~~~~~^~~~~~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:115:29: error: cannot convert value of type 'Double' to type 'NSNumber' in coercion
        return .number(self.rawValue as NSNumber)
                       ~~~~~^~~~~~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:121:29: error: cannot convert value of type 'Float' to type 'NSNumber' in coercion
        return .number(self.rawValue as NSNumber)
                       ~~~~~^~~~~~~~
/home/rlovelett/Source/langserver-swift/.build/checkouts/Ogra.git-4459770976581387768/Sources/Encodable.swift:127:29: error: cannot convert value of type 'UInt' to type 'NSNumber' in coercion
        return .number(self.rawValue as NSNumber)
                       ~~~~~^~~~~~~~
error: terminated(1): /usr/bin/swift-build-tool -f /home/rlovelett/Source/langserver-swift/.build/debug.yaml main output:

Documentation

  • Update the README

@felix91gr
Copy link
Collaborator

What does waitForDataInBackgroundAndNotify do? Is it related to File Events?

@felix91gr
Copy link
Collaborator

No, it is actually a part of Foundation and it’s not currently implemented. We’ll have to do something about it, unless the corelibs team surprises us with a patch that implements that.

@RLovelett
Copy link
Owner Author

swiftlang/swift-corelibs-foundation#1427

The author should stop being lazy and finish the requested feedback. 😏

@felix91gr
Copy link
Collaborator

Omg, I didn't realise you were working on that! Yes, I agree 😜 but also I think his pace might be different. We should not be pressuring him :)

@felix91gr
Copy link
Collaborator

How're we doing logging? Because tracelog is an option to have cross-platform logging :)

@felix91gr
Copy link
Collaborator

PS: I edited the original to-do list so that it's easier to follow, how's it look?

@RLovelett
Copy link
Owner Author

PS: I edited the original to-do list so that it's easier to follow, how's it look?

LGTM 👍

How're we doing logging? Because tracelog is an option to have cross-platform logging :)

So I will be honest and say I haven't put too much thought into logging. So I'll try and stop this from becoming a stream of consciousness.

My two platforms I daily drive are macOS and Fedora. On macOS I want the logging to be done using Unified logging or os_log and on Fedora I want the logging to be available inside the systemd journal, e.g., journalctl. So does that limit or select the loggers we can use? I have no idea. Do we need to do that on the first iteration of logging? Probably not.

The thing that we absolutely cannot do is write to stdout. That is how the LSP and VSCode talk to one another. So if tracelog outputs to stdout then we'll need a different solution.

Other than that, I think its probably best to just try some out and see what happens.

@keegancsmith
Copy link

LSP also defines window/logMessage

@felix91gr
Copy link
Collaborator

LGTM 👍

Awesome :)

The thing that we absolutely cannot do is write to stdout. That is how the LSP and VSCode talk to one another. So if tracelog outputs to stdout then we'll need a different solution.

That seems reasonable.

So looking at TraceLog's Readme (under Configuration), I think we can definitely avoid writing to stdout and possibly configure exactly where do we want it to go depending on the OS:

Log output can be configured globally using the LOG_ALL variable, by TAG name using the LOG_TAG_ variable pattern, and/or by a TAG prefix by using the LOG_PREFIX_ variable pattern.

@felix91gr
Copy link
Collaborator

LSP also defines window/logMessage

Ohh, that is very interesting. Maybe we can pipe the logs to that eventually, or some of them at least (the ones relevant to have on the client's side)

Is this the kind of logging you meant in the to-do list, Ryan? (I know very little about the LSP so I couldn't say)

@RLovelett
Copy link
Owner Author

LSP also defines window/logMessage

Absolutely I think that's a good one too. Traditionally I didn't use that one because when I was first starting this thing I really wanted to be able to log the raw bytes of the protocol. So if you were doing that over the logMessage API it would be a runaway feedback loop. 😄

So for a long time I was just logging every new message into a different file.

Eventually this became too noisy and I fell back to os_log.

This struck a nice balance between being able to see all the low-level logs from the server and also giving an easy filter mechanism.

I still think that window/logMessage has value. Though right now the challenge is what are messages that are for developers of the LSP and what are user facing log messages.

Also, if you look at the main run loop. It is pretty poorly structured to handle injecting out of band messages. The main run loop is basically designed to receive a request from the client and respond. It is not really designed to just say something without being prompted first. That's a design flaw by me.

Is this the kind of logging you meant in the to-do list, Ryan? (I know very little about the LSP so I couldn't say)

No the logging I want to fix in the todo list is this.

@felix91gr
Copy link
Collaborator

Also, if you look at the main run loop. It is pretty poorly structured to handle injecting out of band messages. The main run loop is basically designed to receive a request from the client and respond. It is not really designed to just say something without being prompted first. That's a design flaw by me.

It's not like this was another one amongst the tens of LSP implementations for Swift. This was the first one. I wouldn't blame you for having a design mistake in something that was not only entirely new, but also very much urgently needed.

Maybe the design could be reworked after everything is cross-platform and stable.

Is this the kind of logging you meant in the to-do list, Ryan? (I know very little about the LSP so I couldn't say)

No the logging I want to fix in the todo list is this.

I see. I'll read the docs of TraceLog in more detail, I think it could work for this.

@felix91gr
Copy link
Collaborator

felix91gr commented May 26, 2018

Update on TraceLog:

  1. It can do what we'd like, that is,

My two platforms I daily drive are macOS and Fedora. On macOS I want the logging to be done using Unified logging or os_log and on Fedora I want the logging to be available inside the systemd journal, e.g., journalctl.

Is very much possible :D

  1. Tony thinks this use case is so good that he wants to help directly by implementing it himself ❤️❤️❤️

@RLovelett
Copy link
Owner Author

RLovelett commented May 27, 2018

Okay. I've gotten it "working". 🎉

peek 2018-05-27 13-06

I had to kludge a bunch of patches and compile my own copy of Swift in order to get it to work. But it does talk to SourceKit and then back to VSCode. So it's a good proof of concept.

Still many hours left to go but I have made significant progress.

@felix91gr
Copy link
Collaborator

OMG! :D

YOU CAN DOOO EEEET ✊

...how did you get past the Foundation problems? Are you sneakily using your corelibs PR? :)

@RLovelett
Copy link
Owner Author

RLovelett commented May 27, 2018

...how did you get past the Foundation problems? Are you sneakily using your corelibs PR? :)

Yup. I've compiled my own version of Swift 4.2. I'm using using my patch(es) and a few others that I've not published yet. I'm compiling swift, swift-stdlib and libdispatch in debug mode so I can actually use lldb against each of those components.

I've actually refactored the run loop to not use the old patch needed for Foundation. It now just uses DispatchIO directly. Which actually, I think, makes it more performant.

The bad news is that now it depends on this patch. So I just traded one issue in corelibs for another I suppose. 🤷‍♂️ 🤦‍♂️

@felix91gr
Copy link
Collaborator

felix91gr commented May 27, 2018

I'm compiling swift, swift-stdlib and libdispatch in debug mode. So I can actually use lldb against each of those components.

Wow. Having fiddled a little bit with compiling the toolchain, I know that's a ton of work. 🙇‍♂️ thank you

I've actually refactored the run loop to not use the old patch needed for Foundation. It now just uses DispatchIO directly. Which actually, I think, makes it more performant.

The bad news is that now it depends on this patch. So I just traded one issue in corelibs for another I suppose. 🤷‍♂️ 🤦‍♂️

Well, that patch looks certainly much, much simpler. So that's great! It should be merged soonish, I'd say.

The performance gains are great as well. Good job! ^^

@RLovelett RLovelett self-assigned this May 28, 2018
@felix91gr
Copy link
Collaborator

I've updated the to-do list to reflect your new PR 👍

@RLovelett RLovelett force-pushed the fedora-linux-swift-4.1 branch 3 times, most recently from c1ba9bc to 1a743f4 Compare May 29, 2018 00:39
RLovelett and others added 3 commits May 28, 2018 22:49
… name was different, now they are the same.

There are 3 FIXMEs in the `LinuxMain.swift` file. Those are related to test files that make the test suite crash.
felix91gr and others added 4 commits May 28, 2018 22:49
Added guard statements to replace forced unwraps that would otherwise crash Linux when running certain tests.
Now that those tests are safe, I've enabled them on Linux.
Now test coverage is complete on Linux.
@RLovelett
Copy link
Owner Author

@felix91gr the cross platform logging wasn't as straight forward as we might have hoped I take it.

Swift on Linux is not for the faint of heart. 😏 🤣

@felix91gr
Copy link
Collaborator

the cross platform logging wasn't as straight forward as we might have hoped I take it.

Hahaha, I know right? Ah well. I'm gonna see if I can persuade somebody who's at WWDC s.t. they can get a word in for us for expanding the os_log API.

Swift on Linux is not for the faint of heart.

Last year it was oh so much worse 🤣 but it's getting better! And thanks to people like you and @vknabel, among many others, we can push it forward even faster :). IMO the most important part of a project like Swift is the community behind it, and we have a really welcoming one, with very kind people all around.

I've also seen great disposition on the corelibs-foundation team. They really want to complete the library. That will be a huge push for cross-platform compatibility - more or less half of the projects I've been helping to port, rely on unimplemented pieces of the library.

@RLovelett
Copy link
Owner Author

And thanks to people like you and @vknabel, among many others, we can push it forward even faster

I don't know if I have said or not but I've hit a road block since I cannot actually debug the server on Linux the same way I do on macOS. I'm now learning how LLDB works and trying (so far unsuccessfully) to implement the capability on Linux. 🤞

IMO the most important part of a project like Swift is the community behind it, and we have a really welcoming one, with very kind people all around.

Could not agree more.

more or less half of the projects I've been helping to port, rely on unimplemented pieces of the library

That aligns with my experience too.

Keep up the great work!

@felix91gr
Copy link
Collaborator

I don't know if I have said or not but I've hit a road block since I cannot actually debug the server on Linux the same way I do on macOS. I'm now learning how LLDB works and trying (so far unsuccessfully) to implement the capability on Linux. 🤞

I've seen your quest for LLDB at the forums. I'm crossing my fingers for you as well!
If I got it correctly, LLDB support at the langserver level means that you can do step-by-step debugging right there in the IDE, like in Visual Studio or Eclipse?

Keep up the great work!

You too! ^^

@patilarpith
Copy link

Following

@tonystone
Copy link

@RLovelett do you need assistance adding TraceLog and AdaptiveWriter for "Cross-platform logging"? I should have some time shortly and would be happy to assist when I do.

@RLovelett
Copy link
Owner Author

Absolutely I'd love the assistance. @felix91gr was the one for the original "vision" of how to do this feature but certainly I can help answer questions. If you have a vision for it by all means move forward with it.

@tonystone
Copy link

@RLovelett Ok, I suggest that TraceLog is added in a branch off of master in a separate PR, then pulled into here once merged with master. That would isolate out the changes and allow easier review and testing. TraceLog is already cross-platform. The new AdaptiveWriter can be added in that branch which will also satisfy the requirement in this PR/branch. The AdaptiveWriter writes to os_log (Unified Logging) on Darwin and SD journal on Linux so we'd be all set. We'd be able to remove all the #if os() statements currently used for logging. Thoughts?

@RLovelett
Copy link
Owner Author

Totally agree. That is a great idea. Especially love the idea of it being done directly off of master. Easier to review and move forward.

@tonystone
Copy link

Great, as soon as I free up a bit, I'll get setup with your dev environment, create the branch and get started.

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

Successfully merging this pull request may close these issues.

5 participants