Nexus-Mods / NexusMods.App

Home of the development of the Nexus Mods App
https://nexus-mods.github.io/NexusMods.App/
GNU General Public License v3.0
1.05k stars 47 forks source link

Support for multiple application instances rework #620

Closed Al12rs closed 9 months ago

Al12rs commented 1 year ago
status: proposed
date: 2023-09-11 when the decision was last updated
deciders: -

Multiple application instances support and implementation design

Context and Problem Statement

Multiple application instances support means allowing users to open multiple windows of the App and perform operations from them without incurring in errors, race conditions or general weirdness.

This is desirable for the following scenarios:

This is technically problematic for the following reasons:

Current situation:

Currently the App does allow opening multiple instances at the same time. This is done through the use of two Sqlite db instances, one for the DataModel information, another used as a makeshift Inter-Process Communication tool.

All application instances behave as peers when accessing the DB instances, and this can cause inefficiencies and delays. In particular the IPC part of the solution has caused many issues with long delays and dropped messages, causing many of the Flacky tests failures.

The application UI is usually able to correctly reflect latest state of the DataModel, thanks to reactive Data binding, but the application is still fairly simple and properly supporting multi instance might become harder as more features and more complex functionalities are added. Already some problems exist with Apply and loadout selection for downloads.

Considered Options

  1. Forgo Multi-Instance support completely
  2. Offer only limited multi instance support, for power-users, with disclaimers and known limitations.
  3. Support Multi-Instance using the current Sqlite based peer access architecture
  4. Support Multi-Instance using current peer architecture, but move away from Sqlite for the IPC part and use ad-hoc IPC solution (not many that are multiplatform).
  5. Support Multi-Instance with new IPC solution and a centralized master process in charge of synchronization and DataModel db access.
  6. Single instance, but with CLI IPC
## Decision Outcome

Chosen option: "{title of option 1}", because
{justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force {force} | … | comes out best (see below)}.

<!-- This is an optional element. Feel free to remove. -->
### Consequences

* Good, because {positive consequence, e.g., improvement of one or more desired qualities, …}
* Bad, because {negative consequence, e.g., compromising one or more desired qualities, …}
* … <!-- numbers of consequences can vary -->

<!-- This is an optional element. Feel free to remove. -->
## Validation

{describe how the implementation of/compliance with the ADR is validated. E.g., by a review or an ArchUnit test}

Pros and Cons of the Options

1. Forgo Multi-Instance support completely

Restrict application to only one instance at a time. This behaviour is pretty common for many applications and not unreasonable. Though, experiences from other Managers (Vortex, MO2) have shown that some users would still like to be able to open multiple instances, even at the cost of potential inconsistency.

Good, because:

Bad, because:

2. Offer only limited multi instance support, for power-users, with disclaimers and known limitations.

This is what MO2 is currently doing, offering multi instance support hidden behind a command line parameter. The main use case is to that of using the second window as reference to compare with another managed instance of the same game.

Good, because:

3. Support Multi-Instance using the current Sqlite based peer access architecture

Good, because:

4. Support Multi-Instance using current peer architecture, but switch IPC solution

Good, because:

5. Support Multi-Instance, switch IPC solution, use centralized master process for DataModel db access.

Good, because:

Bad, because:

6. Single instance, but with CLI IPC

Launching the CLI without the UI running would launch the UI. Once the UI is launched, future invocations of the UI would load a new window in the same UI process. We could have the CLI pass flags into the UI when it starts it to have the UI start minimized, in the system tray, etc. The UI could auto-exit if it was created from the CLI and it's been idle for awhile.

Good, because

More Information

Al12rs commented 1 year ago

Please feel free to add the pros and cons of the various options and discuss opinions here

BellCubeDev commented 1 year ago

Perhaps a single process could be used to track locks and changes and communicate these to the other processes. For example, say one instance starts applying a modlist. We may want to lock the database while this happens. Now suppose I installed a mod via the CLI. The mediator process would signal to the UI that it should update accordingly.

I can't provide implementation details due to lack of familiarity, but the general idea is here.

Sewer56 commented 9 months ago

This was formalized into the docs as of commit https://github.com/Nexus-Mods/NexusMods.App/commit/8f278bb5cbb8fe211c47c170d89b31d0f26794a5

Doc Page: https://nexus-mods.github.io/NexusMods.App/decisions/backend/0012-single-process-application/

The results of that ADR are near completion (Event Sourcing, Workspace Implementation). As those have their own separate issues, and the text of this ADR is in main, I'm closing this.

If there's any objections, please re-open this.