fix: ll-package-manager process start abnormal#1713
Conversation
Remove the DBus connection check for ll-package-manager and always start a new process. The previous logic attempted to reuse an existing instance but the connection check was unreliable and introduced complexity. Simplify by always spawning a new process via sudo and sleeping to ensure readiness. Log: ll-cli now always starts a new package-manager process instead of reusing existing one Influence: 1. Test normal command execution after the change 2. Verify that only one package-manager process runs when invoked multiple times (if needed) 3. Ensure that existing operations (install, remove, etc.) still work correctly 4. Check for any race conditions or startup failures due to concurrent launches 5. Validate that the sleeping interval (1s) is sufficient for the package-manager to initialize
There was a problem hiding this comment.
Code Review
This pull request removes the connection check for ll-package-manager, opting to always spawn a new process followed by a hardcoded 1-second sleep. The reviewer points out that always starting a new process is inefficient and causes socket binding errors. Furthermore, the hardcoded sleep introduces a race condition. The reviewer explains that the original connection check failed due to Qt caching peer-to-peer DBus connections, and provides a robust alternative that properly disconnects to clear the cache and uses a retry loop to wait for the socket to become ready.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| startProcess("sudo", | ||
| { "--user", | ||
| LINGLONG_USERNAME, | ||
| "--preserve-env=QT_FORCE_STDERR_LOGGING", | ||
| "--preserve-env=QDBUS_DEBUG", | ||
| LINGLONG_LIBEXEC_DIR "/ll-package-manager", | ||
| "--no-dbus" }); | ||
| using namespace std::chrono_literals; | ||
| std::this_thread::sleep_for(1s); |
There was a problem hiding this comment.
Issue: Unreliable Connection Check & Hardcoded Sleep Race Condition
-
Why the previous connection check was "unreliable":
Qt caches peer-to-peer DBus connections internally by name. WhenQDBusConnection::connectToPeerwas called with the name"ll-package-manager", it registered that connection. If the connection failed or got disconnected, it remained in Qt's internal registry as an invalid connection. Subsequent calls toconnectToPeerwith the same name (such as incli.cpp) would return the cached invalid connection instead of attempting a new connection. To fix this, you must callQDBusConnection::disconnectFromPeer(name)to remove it from the registry. -
Spawning redundant processes:
Always starting a new process viasudowhen one is already running wastes system resources and spams the system logs with socket binding errors (LogE("listen on socket: ...")) from the newly spawned daemon failing to bind to the active socket. -
Hardcoded Sleep Race Condition:
A hardcoded1ssleep is a classic race condition. On slow or heavily loaded systems, the daemon might take longer than 1 second to initialize, causing the subsequent connection to fail. On fast systems, it introduces an unnecessary 1-second delay.
Solution:
Restore the connection check using a temporary connection name, ensure we call disconnectFromPeer to avoid caching issues, and implement a fast retry loop (up to 3 seconds with 100ms intervals) to wait for the socket to become ready.
const auto pkgManAddress = QString("unix:path=/tmp/linglong-package-manager.socket");
// Check if ll-package-manager is already running using a temporary connection name.
// We must disconnect from peer afterwards to avoid caching an invalid connection in Qt's registry.
bool alreadyRunning = false;
{
auto checkConn = QDBusConnection::connectToPeer(pkgManAddress, "ll-package-manager-check");
if (checkConn.isConnected()) {
alreadyRunning = true;
}
QDBusConnection::disconnectFromPeer("ll-package-manager-check");
}
if (!alreadyRunning) {
startProcess("sudo",
{ "--user",
LINGLONG_USERNAME,
"--preserve-env=QT_FORCE_STDERR_LOGGING",
"--preserve-env=QDBUS_DEBUG",
LINGLONG_LIBEXEC_DIR "/ll-package-manager",
"--no-dbus" });
// Wait for the socket to become ready instead of a hardcoded sleep
using namespace std::chrono_literals;
bool connected = false;
for (int i = 0; i < 30; ++i) {
auto conn = QDBusConnection::connectToPeer(pkgManAddress, "ll-package-manager-check");
if (conn.isConnected()) {
connected = true;
QDBusConnection::disconnectFromPeer("ll-package-manager-check");
break;
}
std::this_thread::sleep_for(100ms);
}
if (!connected) {
LogW("ll-package-manager socket is not ready after 3 seconds");
}
} else {
LogD("ll-package-manager is already running, reuse existing process");
}|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: dengbo11 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
Remove the DBus connection check for ll-package-manager and always start a new process. The previous logic attempted to reuse an existing instance but the connection check was unreliable and introduced complexity. Simplify by always spawning a new process via sudo and sleeping to ensure readiness.
Log: ll-cli now always starts a new package-manager process instead of reusing existing one
Influence: