📜 ⬆️ ⬇️

“We try to ensure that User Experience does not differ in different operating systems” - Interview with Rider developers from JetBrains

In early January, JetBrains announced the development of Rider, a cross-platform IDE based on ReSharper and IntelliJ platform, available under Windows, Linux and Mac OS X, and including all ReSharper chips, and supporting the .NET Framework, Mono and CoreCLR. It is assumed that the development will be completed by the autumn of this year, and everyone will be able to try the environment "per tooth" in the framework of the Early Access Program.



Rider has been repeatedly mentioned on the Habré, but in order to give our readers a look at the development process “from the inside,” while understanding the specifics of the process at different stages of production, we turned to JetBrains and answered our questions:
')

What part of the Rider project are you responsible for? What tasks are you assigned?

Kirill Skrygan:

I am the team leader of the Rider project. My tasks include planning tasks, coordinating the whole team, and in part, product design. In addition, I program a lot, I am responsible for the synchronization of texts, editors, code completion, and a bunch of minor, smaller tasks.

Dmitry Ivanov:

I do a reactive data transfer protocol between Java and .NET.

Andrey Akinshin:

There are a lot of parts in Ryder and they are all closely related to each other. As a rule, we have a responsible person for each subsystem. But in practice, in addition to their area of ​​responsibility, they have to actively interact with the team and help to refine other subsystems. I am now actively engaged in NuGet-manager and support of unit tests.

What was the most difficult to implement from a technical point of view?

Kirill Skrygan:

The interaction between the frontend and backend should be consistent, but at the same time fast. You can, of course, drive all data through the main process flows - but will it be fast? Therefore, we have moved to a model where the two processes reactively interact with each other in a multithreaded mode. It seems to me that the solution of all the problems encountered in the implementation of this process was the most difficult task.

When designing a Rider, we lay down on an important invariant: a frontend can join an already working backend, at any time - and vice versa. This provides potential functional benefits: for example, the ability to restart the backend while the frontend is running, if something fatal happened in it. However, the main thing that this approach provides is the convenience of writing consistently working code. Indeed, without this invariant, that is, without saving the state of the backend and the frontend, the interaction would be reduced to a banal request - responce architecture. In the case of a complex multi-threaded IDE, this would lead to heaps of unnecessary checks in the code, in the spirit of "can I now accept this request - or wait until I have everything loaded and tell the backend to send me a message that I can already accept?"

Given that we have both frontend and backend - these are complex multi-threaded processes, such an approach would be a direct way to hell of flights and deadlocks. As a result, we come to a model where we have a reactive and changeable state of the model, distributed to both sides of the protocol, to both processes. It turned out something like MVVM architecture. "Like" is purely because we still can not do without the transient transfers of big data. Perhaps, if we didn’t have such a powerful front-end as Intellij Platform, our MVVM would be cleaner.

Dmitry Ivanov:

Get a healthy threading model in a multi-process application. Imagine, we have two code bases - Intellij Idea and ReSharper, each of which has its own understanding of how to live in a multi-threaded environment, its own locks, its own main thread with managed reentrancy, etc. Plus, there are several additional processes: msbuild tasks, debuggers. And now we need to “fly up” with all this, plus get a free environment from lags and not falling apart at the seams.

In the very first prototype - when it was not even called Rider yet - we used Google Protobuf, and built the work based on the usual RPC. Pretty quickly it came to the realization that we want to use the “Idea” as a View, and build the interaction according to the MMVM principle. In the .NET world, we are used to reactive XAML, and we didn’t want to build UI according to other principles that we consider obsolete. There was a question - how to make java Swing get on reactive, interprocess, and even cross-platform rails? As it often happens in JetBrains, none of the existing solutions did not suit us, and we began to develop our own.

The ViewModel is now described in a very short form using the DSL features provided by Kotlin. Real Java and C # classes that are synchronized between processes are generated from the model. Any change in the model that one that on the other hand generates a reaction.

It soon became clear that within the framework of an honest ViewModel, due to the limitations of UI controls and programming complexity, we cannot hold back, and we had to transfer data entirely for some features - for example, Code Completion can transfer all its 50 thousand elements. It really helped that we immediately made the protocol binary and optimized (hello to all opponents of premature optimization =). In general, we don’t stick into protocol performance. My opinion is that, in terms of "convenience / speed", we were in the top ten, having decided to choose such a technical solution.

Andrey Akinshin:

It is difficult to select any one most difficult part. Tasks are very different, each is complex in its own way, every day we have to face new challenges. Say, today you deal with the device of some subsystems in R # and IDEA, tomorrow you are trying to design a reactive-asynchronous model that will allow these subsystems to be friends (and do it quickly and responsively), and the day after tomorrow you are trying to understand Linux version does not work.

What problems arose when developing versions for Linux? MacOS?

Kirill Skrygan:

Under Linux and MacOS, currently the backend code is executed on Mono. The main task was to rewrite the project code in such a way that it would run under Mono in principle, as well as fix all the relevant project infrastructure for it. In addition, we regularly come across various kinds of specific Mono bugs, the search and debugging of which cannot be called a pleasant process.

Banal absence of checks on null in certain cases led to complete crash of backend. To disgrace, I / O code was written simply and slowly in Mono, which, for example, kept the open FileSystemTracker handle for every request without any merge (and here we immediately say hello to OutOfMemory and unobvious performance problems). Starting with some versions, in Mono they stopped laying under the target for web projects. A separate word deserves xbuild, whose API is very creative, which especially concerns the modification of the design model. Something from this we fix in Samo code Mono, supplying our patches, we go around something with our own means. And yet, in general, I can say that I was pleasantly surprised by the quality of work of Mono. Yes, there are bugs, but in general, everything works somehow, and even more or less stable on different platforms - I personally expected the worst.

Dmitry Ivanov:

There were and are having problems with Mono. For example, in version 4.4 we began to hang sockets - it turned out that the bug. Still, the .NET Framework is much more stable. But we do not complain - we send patches =)

Andrey Akinshin:

First, problems were solved by launching R # on Mono (I had to cut dependencies on WPF and COM, redo unsafe magic, edit bugs in Mono itself, etc.). Then we solved platform-specific problems (for example, \ r \ n in R # vs \ n in Idea; interaction with the file system and all that). Now we are actively trying to refine the cross-platform development stacks (for example, learn to be good friends with XBuild).

Is the IDE functionality different under different operating systems? If so, then what?

Kirill Skrygan:

No, almost nothing is different. At least it should not :)

Dmitry Ivanov:

We try to ensure that User Experience does not differ in different operating systems. Well, except that the build systems used are different.

Andrey Akinshin:

Our task is to make the functionality not differ in anything. Sometimes everything is not going as smoothly as we would like, but I think we will cope with version 1.0.

What of the functionality of Rider, in your opinion, is the killer feature when comparing Rider with MSVS?

Kirill Skrygan:

First, just an order of magnitude more powerful functionality in all directions. Ten times more navigation, code analysis and refactoring (quick fixes, intentions, context actions), Solution Wide Analysis, unit-test runner, excellent support for almost all VCS, and many more resarch features that have been successfully created over the last 10 years. Yes, we have not yet managed to “synchronize” everything, but I see no reason why we cannot do this in the near future. Among other things, Rider has excellent support not only for C #, but also for many other languages: JavaScript, TypeScript, HTML, CSS, Razor, VB.NET, Regex, and many others.

Secondly - it is certainly difficult to call it a functional, but already now many of our users point out a very high speed of Rider operation. And this is before we began the active phase of project optimization. It is possible that the fact is that we do not have a 20-year-old COM'a inside :).

Try in Visual Studio with a more or less large project open, make git pull, which will update .csproj files - after that you can safely go and drink tea for half an hour. All the fault of the code itself Visual Studio, which somehow incorrectly restarts MSBuild for changed projects. Generally, for 5 years of working in Resharper, I’ve seen a lot in VS code, for example GC.Collect (), called in a loop :) In this sense, we feel an order of magnitude freer when writing completely our IDE.

Dmitry Ivanov:

The most important thing in my opinion is that we have all the main features of Resharper, and at the same time - the absence of lags. In my opinion, this is more than enough.

Andrey Akinshin:

If you get away from the comparison with Visual Studio, then my favorite feature in Rider is the console built into the IDE. It's just great, I run some console applications every day and enjoy it.

How do you see the scope of Rider today?

Kirill Skrygan:

Working with all those projects with which you worked in Visual Studio, as well as developing cross-platform mobile applications for MacOS, Linux - that is, Rider could well replace Xamarin Studio and Mono Develop. Most of the development team programs Rider in him the same :)

Dmitry Ivanov:

In JetBrains, dogfudding is one of the main development practices. We use Rider to develop Rider . Even without instability, now writing in the Rider IDE with its smooth tapping is a pleasure.

Andrey Akinshin:

This is mainly cross-platform .NET development. If you love Linux or MacOS, but want to write on C # in a very cool full-featured IDE, then Rider is your choice.



Have you already gathered in St. Petersburg? After all, we are still waiting for you on June 3 at the DotNext 2016 Piter conference, where there will be cool reports on Rider:



And the third participant of our interview will give a hardcore report ... about arithmetic (in fact, not everything is so simple):



There will be other reports . So take a T-shirt, jacket, jacket, sweater - and Peter. Who knows how the weather will change in a day.

Source: https://habr.com/ru/post/301754/


All Articles