Parsec Application Architecture
Parsec’s Application Goals are summarised thus:
Parsec aims to be helpful to you and speed up development of anything using web technologies regardless of the platform you are developing on or for.
To achieve these goals, Parsec needs to be ultra-fast and run cross-platform on Windows, OSX and Linux with a consistent user experience.
Cross-platform development is normally a real pain to do well – especially for a desktop application. While it’s difficult to write code that can be used on all platforms, the main issue is having a consistent user interface and experience across operating systems and differing desktop environments (XQuartz, GNOME, KDE).
Until fairly recently, your only real option was to either maintain a separate codebase for each platform written in a platform-native language, or use something like Java with a JRE.
Now, however, we have some amazing (open source!) tools and frameworks that we can use to build a cross-platform application. I intend to make full use of these to build Parsec.
User Interface #
Parsec will use Electron for it’s UI. This will allow me to very easily design an experience in HTML and CSS that will be consistent across each platform.
Worker back-end #
The back-end of Parsec will be written in Rust and be optimised for memory efficiency and concurrency where-ever possible.
Integration #
The front-end UI will use Javascript to communicate with the back-end over the wonders of InterProcess Communication (IPC) sockets.
The front-end is responsible for accepting user input and telling the back-end what to do.
The back-end will be responsible for doing all the heavy lifting – parsing the source code files, building Abstract Syntax Trees and deciding which items to use in the auto-completion at any given time.
Ultimately this will cause some latency overhead, however I have not yet conducted any testing to find out how bad this latency is.
Threading #
Parsec will run (at least) two separate processes - the UI thread and the back-end worker thread. This is for several reasons:
- Electron is not widely regarded as being very efficient and using a lower-level language such as Rust instead of NodeJS to write the complex parsing logic will make the application much more memory efficient and lets me make use of Rust’s built-in concurrency features to process complex tasks simultaneously.
- Separating the UI and the worker thread means that if the worker thread locks up as it processes a complicated task, the UI will still be able to perform without issue. This is important as Parsec will be parsing a lot of raw source code and having a UI that freezes constantly will be unacceptable.
- Writing a lot of complicated Javascript ultimately means using a few dependencies.
This is Plan A. We shall see how good the performance is of an application with an Electron front-end and a Rust back-end actually is. Stay tuned to find out how this turns out…