Closed cloudRoutine closed 8 years ago
I'm completely for this (surprise :) )
@cloudRoutine remember what happened to your very large PR where you rewrite all C# code to F#? That's why I suggest the following steps:
I strongly believe that API should not be thought out first, it should be discovered as we implement p. 1 and 2. So, we should not spend time thinking how we will support formatting, it will be done much easier when some other features have ported to that API.
Well, this would be great. Some thoughts
thanks!
Less code that does the same thing is always better, consolidating the 7 different consumers of FCS into an all powerful language service has always been my goal, its been rather difficult to make it come about though.
oop callbacks should be relatively easy with websockets, which is the big thing we would get for free from http.
If we could structure this at the FCS boundary, and make it an FCS feature, then all F# tooling in all editors could benefit.
Great idea, I think. Just merge Core and FCS and done all further work there. The less moving parts the better.
Do you think it's easier to make VFPT.Core the boundary? If so, do you think other cross-platform editors (Xamarin etc.) should be building on VFPT.Core instead of FCS?
See ^. All the editors win. Cool.
Do you think the API to core is suitable to take out-of-process? Object model APIs generally need to be converted to "service" APIs structured much more like a set of database calls
Of course as it is, Logic -> Core API is not suitable for service at all.
What would you do about reactive callbacks from out-of-process?
In case of "fast TCP" transport callbacks would be done by establishing another TCP connection, in opposite direction (I think this should be done with robust, battle tested (by me as well) libraries like 0MQ).
In case of HTTP, I've no idea :(
oop callbacks should be relatively easy with websockets, which is the big thing we would get for free from http.
Oh, great. Is it possible to use compact protocol like ProtocolBuffers over HTTP?
Yes, you just use the binary output from protobuf and set application/octet-stream
Great. What about suave as a server? Too slow?
@vasily-kirichenko I think it'd be useful to have a feature branch for this objective
And what of the core? A fork of FCS?
Great idea.
I'll add a link https://github.com/OmniSharp/omnisharp-roslyn because it's the same effort for c# based on roslyn ( instead of FCS ). Maybe it's possible to learn about api, tradeoff, mistake because it's a good cross ide story
@vasily-kirichenko Just tested and Suaves latency is on average 165ms For comparison node.js has a latency of 38ms and iron in rust has a latency of 1.59ms
Suave:
Running 10s test @ http://127.0.0.1:8083/
12 threads and 900 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 165.10ms 176.52ms 1.99s 94.46%
Req/Sec 251.60 93.32 777.00 80.75%
27823 requests in 10.06s, 3.94MB read
Socket errors: connect 0, read 1063, write 1, timeout 60
Requests/sec: 2764.77
Transfer/sec: 401.12KB
Node.js
Running 10s test @ http://localhost:8000/
12 threads and 900 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 38.91ms 23.17ms 300.64ms 67.03%
Req/Sec 0.90k 286.63 2.34k 79.36%
104253 requests in 10.05s, 15.51MB read
Socket errors: connect 0, read 872, write 0, timeout 0
Requests/sec: 10373.39
Transfer/sec: 1.54MB
Rust - Iron:
Running 10s test @ http://localhost:3000/
12 threads and 900 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.59ms 1.10ms 117.24ms 99.57%
Req/Sec 3.37k 1.51k 6.69k 64.48%
399493 requests in 10.03s, 43.43MB read
Socket errors: connect 0, read 626, write 0, timeout 0
Requests/sec: 39847.95
Transfer/sec: 4.33MB
wow. 200 ms is too large.
Let's do this. I'm not sure how it turns out to be, but I can play a supporting role in this initiative.
/cc @nosami for his insights from OmniSharp.
as the service backend host, an option i think it's a good candidate is https://github.com/aspnet/KestrelHttpServer. xplat, http, perf oriented (they try really hard), libuv based like node, active and mantained. For development you can use owin directly, or some library compatible with owin.
Another feedback i want to add it's to really try hard to use http directly instead of tcp if performance is enough ( https://github.com/helios-io/helios it's good but tcp oriented, like 0MQ ) . That's remove a needed wrapper for some ide extensions. If http/json performance it's ok for vscode, i think it's ok for others ide (it's possible to plug multiple response content format like protobuff)
I would recommend not to use a HTTP server and use stdio instead for the following reasons :-
omnisharp-roslyn supports both HTTP and stdio - but HTTP is only there for legacy support to retain compatibility with omnisharp-server. VSCode uses stdio/json (for the omnisharp stuff). Performance wise, there's no noticeable difference.
Another point - any performance drops from using an external process are likely to be insignificant compared to the CPU time required by the compiler.
You should enable the server to support text changes (textrange * oldtext * newtext) for input rather than sending the entire buffer across and also for any code generation output.
FCS often requires full text input rather than a diff, a diff could be calculated on the server though prior to feeding FCS.
Yeah. Roslyn accepts full text or a list of text changes. The purpose being to reduce transportation and serialisation costs.
OmniSharp uses something similar to the V8 debugger protocol. Each request gets an incrementing ID from the editor and the server echoes the ID on the response so that the editor can dispatch a callback.
It might be an idea to support the fsautocomplete protocol too for use with other editors and let them adapt to a new protocol in their own time. Anything other than json here could be problematic.
Also, I think this is something that me and @7sharp9 could get behind to use in Xamarin Studio.
Stdio is extremely easy to implement for both the server and the clients (which could be written in any language). Providing that none of the requests are blocking, there shouldn't be any issues.
The OmniSharp request handler is more complex than it needs to be due to DNX weirdness.
We now have a feature branch dedicated to this endeavor https://github.com/fsprojects/VisualFSharpPowerTools/tree/out-of-process-core
Definitely :+1:.
For the HTTP - I'm using it for both Atom and VS Code right now. Suave is bit slow (But I haven't experienced as bad performance as Dave is suggesting - maybe that's mono problem? Can You link me benchmark You were running, @7sharp9? ). Probably JSON serialization have bigger impact.
Lack of pushing from server is not a problem ( what may be connected with limited set of features we have in FSAC)
Also vim, emacs and sublime (?) are using old FSAC protocol and stdio. @rneatherway can tell us more about it.
While it would be great to have super fast communication layer, I still think performance gains would be small - our main performance problem is compiler itself. So I would more focus on making it usable in easy way from all interested clients.
So I would more focus on making it usable in easy way from all interested clients.
I disagree. Any comm layer which impacts overall performance more that say 5% should not be used (in VFPT I mean. If other clients can live with it, plug whatever they want).
Lack of pushing from server is not a problem ( what may be connected with limited set of features we have in FSAC)
Not sure exactly what you mean here, because FSAC currently returns the results of some requests asynchronously, such as errors and colorization information.
Suave version doesn't support it
OK, understood. I thought you were talking about the whole app. On 16 Jan 2016 3:43 pm, "Krzysztof Cieślak" notifications@github.com wrote:
Suave version doesn't support it
— Reply to this email directly or view it on GitHub https://github.com/fsprojects/VisualFSharpPowerTools/issues/1318#issuecomment-172217448 .
The first stage of accomplishing this goal is underway and being tracked in VFPT.Core Refactoring #1406
@dungpa @duckmatt earlier today @vasily-kirichenko ir and I were discussing how to improve VFPT so that it can handle the load of being employed in a production environment managing Solutions with dozens to hundreds of projects.
One way to achieve this is by moving the majority of VFPT's functionality into VFPT.Core Then we can run VFPT.Core as an independent 64bit process and send the results of its computations over sockets via protocol buffers/binary protocol/etc to a much lighter weight VSIX implementation
We also discussed building dependency graphs and symbol and reference caches to speed up refactoring and to enable jump to anywhere
This architecture will also allow VFPT to play a more important role in F# tooling across the various editors. In which case I think it would be prudent to rename at least the core to
FSharpPowerTools.Core
Information from Core -> Editor
(int * int) list
(int * int) list
(^ often the same but not always)(int * int * enum) list
(int * int * string) list
string list
(int * int * string) list
(int * int) list
path * position
string
Information from Editor -> Core
Open Questions