Skip to content

Conversation

@caixr23
Copy link
Contributor

@caixr23 caixr23 commented Jan 19, 2026

The connection selection logic was moved to the beginning of enableDevice function to ensure it runs before enabling networking. This prevents potential race conditions where network connections might change after enabling the device. The connection selection algorithm now correctly updates maxTs variable when finding the most recent autoconnect connection.

Log: Fixed connection selection timing issue during device activation

Influence:

  1. Test device activation with multiple available connections
  2. Verify autoconnect functionality works correctly
  3. Check that the most recent connection is properly selected
  4. Test network activation with disabled networking
  5. Verify connection selection when no autoconnect connections exist

fix: 将连接选择逻辑移到网络启用之前

连接选择逻辑被移到 enableDevice 函数的开头,确保在网络启用之前运行。这可
以防止在启用设备后网络连接可能发生变化的潜在竞争条件。连接选择算法现在在
找到最新的自动连接连接时正确更新 maxTs 变量。

Log: 修复设备激活期间连接选择时机问题

Influence:

  1. 测试具有多个可用连接时的设备激活
  2. 验证自动连接功能正常工作
  3. 检查是否正确选择了最新连接
  4. 测试网络禁用状态下的网络激活
  5. 验证没有自动连接连接时的连接选择

PMS: BUG-336935

Summary by Sourcery

Adjust device activation flow to select the appropriate autoconnect connection before enabling networking and correct the timestamp-based selection logic.

Bug Fixes:

  • Resolve a race condition by performing connection selection before enabling networking during device activation.
  • Fix autoconnect selection to update and use the latest connection timestamp when determining the preferred connection.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 19, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Moves connection selection earlier in NetworkThread::enableDevice to avoid races with networking enablement and fixes the autoconnect timestamp comparison so the most recent connection is selected correctly.

Sequence diagram for updated enableDevice connection selection timing

sequenceDiagram
    actor System
    participant NetworkThread
    participant Device
    participant Connection
    participant NetworkManager

    System->>NetworkThread: enableDevice(device)
    activate NetworkThread

    Note over NetworkThread,Device: 1) Select autoconnect connection before enabling networking
    NetworkThread->>Device: availableConnections()
    Device-->>NetworkThread: connPaths

    loop for each connPath in connPaths
        NetworkThread->>Connection: connPath.settings()
        Connection-->>NetworkThread: settings
        alt settings.autoconnect is true
            NetworkThread->>Connection: settings.timestamp()
            Connection-->>NetworkThread: ts
            alt ts is newer than maxTs or no selection yet
                NetworkThread-->>NetworkThread: update maxTs and connPath0
            end
        else settings.autoconnect is false
            NetworkThread-->>NetworkThread: skip connection
        end
    end

    NetworkThread->>NetworkManager: isNetworkingEnabled()
    NetworkManager-->>NetworkThread: enabled
    alt enabled is false
        NetworkThread->>NetworkManager: setNetworkingEnabled(true)
    end

    alt connPath0 is empty
        NetworkThread-->>System: "/"
    else
        NetworkThread-->>System: connPath0
    end
    deactivate NetworkThread
Loading

Flow diagram for autoconnect connection selection in enableDevice

flowchart TD
    A[Start enableDevice] --> B[Get connPaths from device.availableConnections]
    B --> C[Initialize connPath0 as empty]
    C --> D[Initialize maxTs as default QDateTime]
    D --> E{More connPaths?}
    E -->|No| F{Is connPath0 empty?}
    F -->|Yes| G[Return /]
    F -->|No| H[Return connPath0]

    E -->|Yes| I[Take next connPath]
    I --> J[Load settings from connPath.settings]
    J --> K{settings.autoconnect?}
    K -->|No| E
    K -->|Yes| L[ts = settings.timestamp]
    L --> M{ts > maxTs or connPath0 is empty?}
    M -->|No| E
    M -->|Yes| N[Set maxTs = ts and connPath0 = connPath.path]
    N --> E
Loading

File-Level Changes

Change Details Files
Reordered connection selection to occur before enabling networking and corrected the autoconnect selection logic to track the latest timestamp.
  • Invoke device->availableConnections() and iterate over them at the start of enableDevice instead of after networking is enabled.
  • Filter connections by settings()->autoconnect() and compute the most recent connection using a maxTs QDateTime accumulator.
  • Ensure both maxTs and connPath0 are updated when a newer autoconnect connection is found, and return either the selected connection path or "/" if none is available.
network-service-plugin/src/system/networkthread.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • When picking the most recent autoconnect connection, consider basing the initialization/guard purely on maxTs.isValid() (or !maxTs.isNull()) instead of connPath0.isEmpty() so the selection logic is clearly tied to timestamp validity rather than the side effect of having chosen a path.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When picking the most recent autoconnect connection, consider basing the initialization/guard purely on `maxTs.isValid()` (or `!maxTs.isNull()`) instead of `connPath0.isEmpty()` so the selection logic is clearly tied to timestamp validity rather than the side effect of having chosen a path.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

The connection selection logic was moved to the beginning of
enableDevice function to ensure it runs before enabling networking.
This prevents potential race conditions where network connections might
change after enabling the device. The connection selection algorithm
now correctly updates maxTs variable when finding the most recent
autoconnect connection.

Log: Fixed connection selection timing issue during device activation

Influence:
1. Test device activation with multiple available connections
2. Verify autoconnect functionality works correctly
3. Check that the most recent connection is properly selected
4. Test network activation with disabled networking
5. Verify connection selection when no autoconnect connections exist

fix: 将连接选择逻辑移到网络启用之前

连接选择逻辑被移到 enableDevice 函数的开头,确保在网络启用之前运行。这可
以防止在启用设备后网络连接可能发生变化的潜在竞争条件。连接选择算法现在在
找到最新的自动连接连接时正确更新 maxTs 变量。

Log: 修复设备激活期间连接选择时机问题

Influence:
1. 测试具有多个可用连接时的设备激活
2. 验证自动连接功能正常工作
3. 检查是否正确选择了最新连接
4. 测试网络禁用状态下的网络激活
5. 验证没有自动连接连接时的连接选择

PMS: BUG-336935
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码的主要改动是将"查找并选择最佳连接"的逻辑块从函数后半部分移动到了函数前半部分(在启用网络之前)。以下是对这段代码的详细审查和改进建议:

1. 语法逻辑审查

优点:

  • 代码逻辑上没有语法错误,能够正常编译。
  • 使用了 C++11 的 auto 关键字和基于范围的 for 循环,代码较为简洁。
  • 移动逻辑位置是合理的:在执行 NetworkManager::setNetworkingEnabled(true) 等可能触发异步状态变更的操作之前,先获取当前快照(availableConnections),避免了在状态变更过程中获取数据可能产生的不确定性。

问题与建议:

  • 变量命名不够清晰connPath0 这个变量名含义不明确,它实际上存储的是"最近一次使用的自动连接路径"。建议重命名为 lastUsedAutoConnectPathpreferredConnPath
  • 逻辑判断冗余:在 if (maxTs < ts || connPath0.isEmpty()) 中,connPath0.isEmpty() 仅在第一次循环时为真。虽然这能处理空列表的情况,但可以更优雅地处理。

2. 代码质量审查

  • 空指针风险connPath->settings() 返回的是指针。虽然 NetworkManager 库通常保证非空,但在防御性编程中,最好增加判空检查,或者确认该库的实现保证了这一点。
  • 代码可读性:提取逻辑块后,函数中间穿插了启用网络的逻辑。建议将"查找最佳连接"的逻辑提取为一个独立的私有辅助函数(Helper Function),例如 findLastUsedAutoConnection,这样 enableDevice 的主流程会更清晰。

3. 代码性能审查

  • 性能影响:原代码在移动位置后,性能上没有明显变化。availableConnections()settings() 的调用次数相同。
  • 潜在优化:如果 availableConnections 列表非常大,遍历可能会有轻微开销,但在网络配置场景下,连接数量通常很少(个位数),因此无需过度优化。

4. 代码安全审查

  • 线程安全NetworkThread 暗示这是一个多线程环境。NetworkManager 的操作通常是异步的。虽然这里只是读取属性,但需确保 device 指针在执行期间有效,且 availableConnections 返回的列表在遍历过程中不会被底层库意外修改(通常 Qt 的智能指针能较好处理)。
  • 状态一致性:将查找逻辑移到 setNetworkingEnabled 之前是更安全的做法。如果在启用网络之后再查找,可能会因为网络状态的异步变化导致获取到的连接列表与预期不符。

改进后的代码建议

建议将查找逻辑提取为独立函数,并优化变量命名:

// 建议在类内部添加一个私有辅助函数
QString NetworkThread::findPreferredConnection(const NetworkManager::Device::Ptr &device)
{
    auto availableConnections = device->availableConnections();
    qCDebug(DSM()) << "available connections:" << availableConnections;

    QString preferredPath;
    QDateTime maxTimestamp;

    for (const auto &connection : availableConnections) {
        // 防御性编程:检查指针有效性
        if (!connection) {
            continue;
        }

        auto settings = connection->settings();
        if (!settings || !settings->autoconnect()) {
            continue;
        }

        QDateTime ts = settings->timestamp();
        // 更新最新的时间戳和对应的路径
        if (ts > maxTimestamp) {
            maxTimestamp = ts;
            preferredPath = connection->path();
        }
    }

    return preferredPath;
}

QString NetworkThread::enableDevice(NetworkManager::Device::Ptr device)
{
    // 1. 先确定要连接的目标(在状态变更前获取快照)
    QString preferredConnPath = findPreferredConnection(device);

    // 2. 启用网络
    bool enabled = NetworkManager::isNetworkingEnabled();
    if (!enabled) {
        NetworkManager::setNetworkingEnabled(true);
    }

    // ... 原有的设备启用逻辑 ...
    if (!device->isActive()) {
        // ...
    }

    // 3. 返回结果
    return preferredConnPath.isEmpty() ? "/" : preferredConnPath;
}

总结

这次代码修改(移动逻辑块的位置)在逻辑上是正确的,有助于提高状态获取的稳定性。主要改进点在于代码结构可读性。通过提取辅助函数和优化命名,可以使代码更易于维护和理解。同时,增加对指针的非空检查能提高代码的健壮性。

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, mhduiy, ut003640

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@caixr23 caixr23 merged commit 8332828 into linuxdeepin:master Jan 29, 2026
16 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants