[PR #908] [MERGED] Mitigate race conditions and simplify API invocations #1346

Open
opened 2026-01-29 16:59:48 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/ElectronNET/Electron.NET/pull/908
Author: @softworkz
Created: 11/6/2025
Status: Merged
Merged: 11/7/2025
Merged by: @FlorianRappl

Base: developHead: submit_api_consolidation


📝 Commits (3)

  • 93f457d Introduce ApiBase and simplify method invocation
  • 2a6d211 Mitigate race condition, introduce timeout and simplify code for property gets
  • 4c3065c SocketIOFacade: Synchronize un/registration of events

📊 Changes

5 files changed (+423 additions, -975 deletions)

View changed files

src/ElectronNET.API/API/ApiBase.cs (+177 -0)
📝 src/ElectronNET.API/API/App.cs (+38 -220)
📝 src/ElectronNET.API/API/BrowserWindow.cs (+135 -732)
📝 src/ElectronNET.API/Bridge/SocketIOFacade.cs (+40 -21)
📝 src/ElectronNET.API/Common/Extensions.cs (+33 -2)

📄 Description

There's a major design flaw in the API invocations.

The problem is that requests via socket IO are not numbered (like wiht a serial nr) and there can be only a single listener for a certain event name.
This means that when there's an invocation that is waiting for a return and a second invocation is made, the listener for the previous invocation will never be notified.
In combination with the use of TaskCompletionSource, the resulting behavior is that the tasks of such calls were never transitioned to completion (nor errored, nor canceled).

The result: code that was awaiting such tasks remained hanging forever - possibly even preventing the whole application from finishing gracefully (without needing to be forced to).

This PR simplifies those property invocations and it also mitigates those race conditions in a way that only a single invocation (= single TaskCompletionSource) exists for each method at a time. Subsequent calls are just being returned the same task from the TCS.
There can still be situations where there's no return, that's why the PR also introduces a timeout after which the tasks will be canceled. The duration might be debatable or can be made configurable. It's set to 1s at the moment.

Second benefit is the elimination of load of repetitive code. It reduces BrowserWindow from 1.7k to 1.2k lines.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/ElectronNET/Electron.NET/pull/908 **Author:** [@softworkz](https://github.com/softworkz) **Created:** 11/6/2025 **Status:** ✅ Merged **Merged:** 11/7/2025 **Merged by:** [@FlorianRappl](https://github.com/FlorianRappl) **Base:** `develop` ← **Head:** `submit_api_consolidation` --- ### 📝 Commits (3) - [`93f457d`](https://github.com/ElectronNET/Electron.NET/commit/93f457dd0f59813887c29a7abb84a27a1ba0f80c) Introduce ApiBase and simplify method invocation - [`2a6d211`](https://github.com/ElectronNET/Electron.NET/commit/2a6d2117e9fcf94b7c139cbf84fa9c5c0d1e29b5) Mitigate race condition, introduce timeout and simplify code for property gets - [`4c3065c`](https://github.com/ElectronNET/Electron.NET/commit/4c3065c64b86d1c611bc25ab024d3d758df7d28e) SocketIOFacade: Synchronize un/registration of events ### 📊 Changes **5 files changed** (+423 additions, -975 deletions) <details> <summary>View changed files</summary> ➕ `src/ElectronNET.API/API/ApiBase.cs` (+177 -0) 📝 `src/ElectronNET.API/API/App.cs` (+38 -220) 📝 `src/ElectronNET.API/API/BrowserWindow.cs` (+135 -732) 📝 `src/ElectronNET.API/Bridge/SocketIOFacade.cs` (+40 -21) 📝 `src/ElectronNET.API/Common/Extensions.cs` (+33 -2) </details> ### 📄 Description There's a major design flaw in the API invocations. The problem is that requests via socket IO are not numbered (like wiht a serial nr) and there can be only a single listener for a certain event name. This means that when there's an invocation that is waiting for a return and a second invocation is made, the listener for the previous invocation will never be notified. In combination with the use of TaskCompletionSource, the resulting behavior is that the tasks of such calls were never transitioned to completion (nor errored, nor canceled). The result: code that was awaiting such tasks remained hanging forever - possibly even preventing the whole application from finishing gracefully (without needing to be forced to). This PR simplifies those property invocations and it also mitigates those race conditions in a way that only a single invocation (= single TaskCompletionSource) exists for each method at a time. Subsequent calls are just being returned the same task from the TCS. There can still be situations where there's no return, that's why the PR also introduces a timeout after which the tasks will be canceled. The duration might be debatable or can be made configurable. It's set to 1s at the moment. Second benefit is the elimination of load of repetitive code. It reduces BrowserWindow from 1.7k to 1.2k lines. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 16:59:48 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/Electron.NET#1346