Inheriting Torrent Settings #8121

Open
opened 2026-02-21 19:21:31 -05:00 by deekerman · 21 comments
Owner

Originally created by @glassez on GitHub (Nov 29, 2018).

Originally assigned to: @glassez on GitHub.

Let me to introduce "Inheriting Torrent Settings" feature.
It should be a generalized replacement for some existing mechanisms (e.g. Automatic Torrent Management) and bring a convenient way to implement all similar capabilities.

From a user perspective, it is a set of torrent settings (like Save path, Ratio limit, etc.) that have some default values and can be overridden at different levels (e.g. at Category level or Torrent level).
settings

From a developer perspective, it is a set of torrent settings that is bound to each "manageable item" (Application, Category, Torrent).
Each setting can be either set or not set.
The following resolution algorithm is used to obtain the effective value of some setting:

  1. If setting is not set the effective value of parent "manageable item" is used (the setting inherits the value).
  2. If setting is explicitly set its value is resolved relative to the effective value of the parent "manageable item" and then used. By default the resolution simply boils down to returning the value itself. But some particular settings (e.g. Save path) can actually make relative resolution.

Example
Consider the following example of one of the settings (Save path):
inheriting

A value for "Save path" setting of "Torrent A" is not set so it inherits the value from its parent item (Category "Misc"). Category "Misc" also hasn't explicit value of "Save path" and it inherits the value of its parent item (Application default "Save path" setting). So the effective value of "Torrent A" "Save path" setting is "C:\Users\John\Downloads".
"Torrent B" has explicit value of "Save path" setting so the effective value is its value resolved against the effective value of appropriate parent item setting. Since it's absolute path it is used as is.
The effective values for "Save path" setting of all other torrents we get in the same way (e.g. "Torrent E" has "D:\Videos\Movies").

Inheritance of Setting works in two ways:

  1. Real inheritance. When "manageable item" is created some settings are passed as is. When value of one of these settings is changed by the user the "manageable item" calls its children to adjust the appropriate setting.
  2. Create-time inheritance. When "manageable item" is created some settings are resolved against parent item settings so the explicit values are really stored and such settings aren't affected by parent settings changes.

Each setting is mapped to a policy that determines how this setting will be created. There is also a default policy that allows you to not explicitly set all policies.
policies
When a user (or some automation tool) creates Category or adds Torrent it pass "Torrent Settings" that are pre-processed by the Session using Policies. If appropriate Policy is "Bypass" the setting is passed as is. If Policy is "Resolve" the setting is resolved first and passed having explicit value. If an appropriate Policy for some Setting is not set the Default Policy is used.

I want to pre-discuss this feature here and get the main approval before proceeding with its implementation. So waiting for your comments (I'm more interested in the comments of team members, but users can also speak out if someone has something really valuable).
@sledgehammer999, @qbittorrent/demigods, @qbittorrent/frequent-contributors, ping.

Originally created by @glassez on GitHub (Nov 29, 2018). Originally assigned to: @glassez on GitHub. Let me to introduce "Inheriting Torrent Settings" feature. It should be a generalized replacement for some existing mechanisms (e.g. Automatic Torrent Management) and bring a convenient way to implement all similar capabilities. From a user perspective, it is a set of torrent settings (like Save path, Ratio limit, etc.) that have some default values and can be overridden at different levels (e.g. at Category level or Torrent level). ![settings](https://user-images.githubusercontent.com/5063477/49224680-15043580-f3f3-11e8-9619-ff38bef9f8f1.png) From a developer perspective, it is a set of torrent settings that is bound to each "manageable item" (Application, Category, Torrent). Each setting can be either set or not set. The following resolution algorithm is used to obtain the effective value of some setting: 1. If setting is not set the effective value of parent "manageable item" is used (the setting inherits the value). 2. If setting is explicitly set its value is resolved relative to the effective value of the parent "manageable item" and then used. By default the resolution simply boils down to returning the value itself. But some particular settings (e.g. Save path) can actually make relative resolution. **Example** Consider the following example of one of the settings (Save path): ![inheriting](https://user-images.githubusercontent.com/5063477/49224281-17b25b00-f3f2-11e8-9b19-681e896b7ff4.png) A value for "Save path" setting of "Torrent A" is not set so it inherits the value from its parent item (Category "Misc"). Category "Misc" also hasn't explicit value of "Save path" and it inherits the value of its parent item (Application default "Save path" setting). So the effective value of "Torrent A" "Save path" setting is "C:\Users\John\Downloads". "Torrent B" has explicit value of "Save path" setting so the effective value is its value resolved against the effective value of appropriate parent item setting. Since it's absolute path it is used as is. The effective values for "Save path" setting of all other torrents we get in the same way (e.g. "Torrent E" has "D:\Videos\Movies"). Inheritance of Setting works in two ways: 1. Real inheritance. When "manageable item" is created some settings are passed as is. When value of one of these settings is changed by the user the "manageable item" calls its children to adjust the appropriate setting. 2. Create-time inheritance. When "manageable item" is created some settings are resolved against parent item settings so the explicit values are really stored and such settings aren't affected by parent settings changes. Each setting is mapped to a policy that determines how this setting will be created. There is also a default policy that allows you to not explicitly set all policies. ![policies](https://user-images.githubusercontent.com/5063477/49224688-1c2b4380-f3f3-11e8-9e7e-9dcd14a849f6.png) When a user (or some automation tool) creates Category or adds Torrent it pass "Torrent Settings" that are pre-processed by the Session using Policies. If appropriate Policy is "Bypass" the setting is passed as is. If Policy is "Resolve" the setting is resolved first and passed having explicit value. If an appropriate Policy for some Setting is not set the Default Policy is used. I want to pre-discuss this feature here and get the main approval before proceeding with its implementation. So waiting for your comments (I'm more interested in the comments of team members, but users can also speak out if someone has something really valuable). @sledgehammer999, @qbittorrent/demigods, @qbittorrent/frequent-contributors, ping.
Author
Owner

@sledgehammer999 commented on GitHub (Nov 29, 2018):

  1. kudos for the included charts
  2. I agree with the abstract concept
  3. I understand how the inheritable settings can work with Torrents. But you seem to mention other areas where they could be used (Application, Category). Do you have abstract examples on how the settings will work for the other areas?
  4. About policies: Is some example possible to see how they relate to settings?
@sledgehammer999 commented on GitHub (Nov 29, 2018): 1. kudos for the included charts 2. I agree with the abstract concept 3. I understand how the inheritable settings can work with Torrents. But you seem to mention other areas where they could be used (Application, Category). Do you have abstract examples on how the settings will work for the other areas? 4. About policies: Is some example possible to see how they relate to settings?
Author
Owner

@glassez commented on GitHub (Nov 29, 2018):

But you seem to mention other areas where they could be used (Application, Category).

You misunderstood me. They're just handle the Torrent Settings but don't use themselves. See my example carefully.

About policies: Is some example possible to see how they relate to settings?

Tomorrow I will add an example of their work.

@glassez commented on GitHub (Nov 29, 2018): >But you seem to mention other areas where they could be used (Application, Category). You misunderstood me. They're just handle the **Torrent Settings** but don't use themselves. See my example carefully. >About policies: Is some example possible to see how they relate to settings? Tomorrow I will add an example of their work.
Author
Owner

@glassez commented on GitHub (Nov 30, 2018):

Tomorrow I will add an example of their work.

I've added the description of Creation Policies.

@glassez commented on GitHub (Nov 30, 2018): >Tomorrow I will add an example of their work. I've added the description of Creation Policies.
Author
Owner

@glassez commented on GitHub (Nov 30, 2018):

I intend to implement this feature in the application core initially with minimal UI changes. But in the future it will require significant rework and unification.

@glassez commented on GitHub (Nov 30, 2018): I intend to implement this feature in the application core initially with minimal UI changes. But in the future it will require significant rework and unification.
Author
Owner

@Seeker2 commented on GitHub (Dec 9, 2018):

Is this what's necessary to implement separate max connection limits for downloading and seeding torrents? Found here:
[Wishlist] Alternate connections per torrent while seeding - Upload Slots per SEEDING torrent limit!
https://github.com/qbittorrent/qBittorrent/issues/2193
...Which would explain why "Milestone: qBitTorrent v3.2.1" has long-since been passed.

@Seeker2 commented on GitHub (Dec 9, 2018): Is this what's necessary to implement separate max connection limits for downloading and seeding torrents? Found here: [Wishlist] Alternate connections per torrent while seeding - Upload Slots per SEEDING torrent limit! https://github.com/qbittorrent/qBittorrent/issues/2193 ...Which would explain why "Milestone: qBitTorrent v3.2.1" has long-since been passed.
Author
Owner

@rrrevin commented on GitHub (Apr 22, 2019):

Any update on this?

@rrrevin commented on GitHub (Apr 22, 2019): Any update on this?
Author
Owner

@glassez commented on GitHub (Apr 23, 2019):

Any update on this?

Unfortunately, I do not have enough time to make any significant contributions to the project.

@glassez commented on GitHub (Apr 23, 2019): >Any update on this? Unfortunately, I do not have enough time to make any significant contributions to the project.
Author
Owner

@Pentaphon commented on GitHub (Nov 9, 2020):

We should probably take this off the 4.3.1 milestone because there is no way this is going to make that version.

@Pentaphon commented on GitHub (Nov 9, 2020): We should probably take this off the 4.3.1 milestone because there is no way this is going to make that version.
Author
Owner

@radry commented on GitHub (Feb 22, 2021):

How about putting this again on the next milestone? At least 4.4.0?

@radry commented on GitHub (Feb 22, 2021): How about putting this again on the next milestone? At least 4.4.0?
Author
Owner

@damomato commented on GitHub (Mar 5, 2022):

Any updates on this? I would like to set different seeding limits for different categories

@damomato commented on GitHub (Mar 5, 2022): Any updates on this? I would like to set different seeding limits for different categories
Author
Owner

@tayl commented on GitHub (Jan 3, 2023):

+1 for this, setting limits by category would be useful. Stealing someone else's comment from elsewhere as it reflects my own need:

  • I'd like to seed endlessly educational stuff, research, pdfs etc;
  • open-source binaries, linux ISOs etc for few months (by this time probably there is more recent version of mentioned software)
  • art, music, movies to let's say ratio 2
  • other things to ratio 1
@tayl commented on GitHub (Jan 3, 2023): +1 for this, setting limits by category would be useful. Stealing someone else's comment from elsewhere as it reflects my own need: - I'd like to seed endlessly educational stuff, research, pdfs etc; - open-source binaries, linux ISOs etc for few months (by this time probably there is more recent version of mentioned software) - art, music, movies to let's say ratio 2 - other things to ratio 1
Author
Owner

@matthieu-vergne commented on GitHub (May 23, 2023):

May I suggest an architecture for the implementation? Please be aware that I am a Java developer. So I cannot help much on C++ code, but I hope that at design level it can be of some use.

Basic idea

Basically, your default settings would be a SettingsValues instance, and every additional layer below it would be a SettingsCombiner taking the instance of the previous layer as fallbackSettings + another SettingsValues telling what are the values set specifically at this new layer. I call the first one "fallback" because I have first in mind that you want to "fall back" on this instance if the "current settings" does not define a value. The code in the bottom right note implements such a fallback strategy. The key point is to call the fallback only if needed.

If the user changes the save path of the default settings, it calls savePath(newPath) on the SettingsValues used for the defaults. If the user changes the save path of a category, it retrieves the SettingsCombiner at the category level and calls its currentSettings.savePath(newPath) to change the settings at the category level.

Examples of traversing when we retrieve the save path:

  • torrent D: call torrentD.savePath(), look at its currentSettings.savePath(), defined so returns it.
  • torrent C: call torrentC.savePath(), look at its currentSettings.savePath(), not defined so fall back to music.savePath(), look at its currentSettings.savePath(), defined so returns it.
  • torrent A: call torrentA.savePath(), look at its currentSettings.savePath(), not defined so fall back to misc.savePath(), look at its currentSettings.savePath(), not defined so fall back to defaultSettings.savePath(), immediately returns its value because it is a SettingsValues, not a SettingsCombiner.

Settings resolution

Rather than simply falling back on the previous layer, you speak about resolving it against its parent. In this case, the SettingsCombiner uses a more complex implementation, which I abstract in a function:

The function is a bit convoluted, but this is because we don't want to retrieve both paths before to check whether or not it is worth it. Otherwise you would systematically retrieve the settings through all the hierarchy even if you use only one of them.

To avoid that, the "calls" are abstracted through the 3rd argument Settings::savePath, which is java code for a method reference. An object that you can apply on a Settings instance to call its savePath() method (and obtain its returned value). I don't know what would be the equivalent in C++.

The pseudo-code for this function would be the following:

Path currentPath = apply Settings::savePath on currentSettings
if (currentPath is undefined) {
  // Not needed, just return fallback settings
  return apply Settings::savePath on fallbackSettings
} else if (currentPath is relative) {
  // Needed but incomplete, resolve against fallback
  Path parentPath = apply Settings::savePath on fallbackSettings
  Path resultPath = resolve currentPath against parentPath
  return resultPath
} else {
  // Needed and completely override fallback, so no need to go further
  return currentPath
}

When applied to torrent E case:

  1. apply Settings::savePath on torrentE.currentSettings to have currentPath n°1
  2. undefined, so discard currentPath n°1 and apply Settings::savePath on fallback
    1. apply Settings::savePath on movies.currentSettings to have currentPath n°2
    2. defined but relative, so keep currentPath n°2 and apply Settings::savePath on fallback
      1. apply Settings::savePath on videos.currentSettings to have currentPath n°3
      2. defined and absolute so return the currentPath n°3 without going further
    3. resolve currentPath n°2 against the result of the fallback
    4. returns the resolution
  3. returns the result of the fallback

The notions of absoluteness/relativeness are rather trivial for paths, but they have to be interpreted in a generic way to be applicable to other types of data. For instance, what would it mean to have a "relative speed" of download to be resolved on the parent settings? Would it be a factor? But then it would not be a "speed" since a factor has no unit. You can always "fall back" on the parent settings, but the resolution must be considered case by case.

Snapshot

Finally, the notions of "real" and "create-time" inheritance. As far as I understand, you want to remove the capacity for the resulting settings to change based on some changes on some arbitrary layers. Which is what we usually call a snapshot:

Here I add a function in the interface, but assuming we can implement it at this level (default implementation in Java). If it is not the case, you can have this function somewhere else out of this architecture. It would take the source Settings in argument and return the new one after filling it.

@matthieu-vergne commented on GitHub (May 23, 2023): May I suggest an architecture for the implementation? Please be aware that I am a Java developer. So I cannot help much on C++ code, but I hope that at design level it can be of some use. # Basic idea ![](http://www.plantuml.com/plantuml/dsvg/dPBHIiGm44NVynNNjrsX-m6hXGNz0671zxITRejf8ib41Us_srPsfDaeuaj8axatP-xq45XxZeDHlMNohQu9HsBkxIdWNG51lz23vcwpnHxpHW63VhjthzOutHoVYPhbRjcfKIbs9-AE_2IlZGv1_1wrYRHs_TbJ7FC8SZOlsr-PSfVBkfrehMD2vPZT0DScgEktPsx04qTlvVn60MFA8rzd4NTzs4dFPQ8css3cK1ByxKTHf2n9c7Tkg7gxf0pKqNkoBFhzPIEjDgRIzLEcvZzJJdDBg7B9hP91cKBllWLpB43VOYFbLoLiDERibPq3C89CeAH6Mi-yzANwonIai-HlBgulIqPrcDpYO3u1) Basically, your default settings would be a `SettingsValues` instance, and every additional layer below it would be a `SettingsCombiner` taking the instance of the previous layer as `fallbackSettings` + another `SettingsValues` telling what are the values set specifically at this new layer. I call the first one "fallback" because I have first in mind that you want to "fall back" on this instance if the "current settings" does not define a value. The code in the bottom right note implements such a fallback strategy. The key point is to call the fallback only if needed. If the user changes the save path of the default settings, it calls `savePath(newPath)` on the `SettingsValues` used for the defaults. If the user changes the save path of a category, it retrieves the `SettingsCombiner` at the category level and calls its `currentSettings.savePath(newPath)` to change the settings at the category level. Examples of traversing when we retrieve the save path: - torrent D: call `torrentD.savePath()`, look at its `currentSettings.savePath()`, defined so returns it. - torrent C: call `torrentC.savePath()`, look at its `currentSettings.savePath()`, not defined so fall back to `music.savePath()`, look at its `currentSettings.savePath()`, defined so returns it. - torrent A: call `torrentA.savePath()`, look at its `currentSettings.savePath()`, not defined so fall back to `misc.savePath()`, look at its `currentSettings.savePath()`, not defined so fall back to `defaultSettings.savePath()`, immediately returns its value because it is a `SettingsValues`, not a `SettingsCombiner`. # Settings resolution Rather than simply falling back on the previous layer, you speak about resolving it against its parent. In this case, the `SettingsCombiner` uses a more complex implementation, which I abstract in a function: ![](http://www.plantuml.com/plantuml/dsvg/dPB1QiCm38RlUeh_s8pb1R8T2ji330gxAudIXZdsiELkiENTrnXgg9lkK1-4iFJ__YIy3SfUusHej2f-u4wm4zNHxWD-20Xyb3VMmwP2WoKXOEBlL_TbZUD-zodIfrhAQ2PIjnSzY3_9EyCXPBztDb4kNMzxPiTrX7otXEf_ffLYYXNDb6Tz_gthWfGA_XStjQDDWm5Tz5wiPdrJYe61ZMcv-rZfkMUnrgcWTQfkWXkkg2ui4oBWHQEty1ASESgcO7uabAU4lj5qBZRD-SdgYO2PnFPOECkzbgp5bwWVhbjcsfxSucJ-0000) The function is a bit convoluted, but this is because we don't want to retrieve both paths before to check whether or not it is worth it. Otherwise you would systematically retrieve the settings through all the hierarchy even if you use only one of them. To avoid that, the "calls" are abstracted through the 3rd argument `Settings::savePath`, which is java code for a method reference. An object that you can apply on a `Settings` instance to call its `savePath()` method (and obtain its returned value). I don't know what would be the equivalent in C++. The pseudo-code for this function would be the following: ``` Path currentPath = apply Settings::savePath on currentSettings if (currentPath is undefined) { // Not needed, just return fallback settings return apply Settings::savePath on fallbackSettings } else if (currentPath is relative) { // Needed but incomplete, resolve against fallback Path parentPath = apply Settings::savePath on fallbackSettings Path resultPath = resolve currentPath against parentPath return resultPath } else { // Needed and completely override fallback, so no need to go further return currentPath } ``` When applied to torrent E case: 1. apply `Settings::savePath` on `torrentE.currentSettings` to have `currentPath` n°1 2. undefined, so discard `currentPath` n°1 and apply `Settings::savePath` on fallback 1. apply `Settings::savePath` on `movies.currentSettings` to have `currentPath` n°2 2. defined but relative, so keep `currentPath` n°2 and apply `Settings::savePath` on fallback 1. apply `Settings::savePath` on `videos.currentSettings` to have `currentPath` n°3 2. defined and absolute so return the `currentPath` n°3 without going further 3. resolve `currentPath` n°2 against the result of the fallback 4. returns the resolution 3. returns the result of the fallback The notions of absoluteness/relativeness are rather trivial for paths, but they have to be interpreted in a generic way to be applicable to other types of data. For instance, what would it mean to have a "relative speed" of download to be resolved on the parent settings? Would it be a factor? But then it would not be a "speed" since a factor has no unit. You can always "fall back" on the parent settings, but the resolution must be considered case by case. # Snapshot Finally, the notions of "real" and "create-time" inheritance. As far as I understand, you want to remove the capacity for the resulting settings to change based on some changes on some arbitrary layers. Which is what we usually call a snapshot: ![](http://www.plantuml.com/plantuml/dsvg/bP91QiCm44NtEiKicu9x0DD5e3r08T3zH1vRff8cIEEaaERkbLGYMZcbT3E8-VzRty_UHi4WYxDgza9XH4sm8v7PJn7E2Y3YaLvGpDq6UiY7j7Fu_imdRnc7tO5eA5evvO37GpGiULaVfIxAin1O6WLuhFk-lzf_9ZLQ6o4D44F0QGHm98Q7c8p2C94KIIyXa1Suebqe9Vm0EX0APH_MUrw_vDCi9iVSWwBap9MK4fweN71MscACRUWxXTyPL0AtaTLT7fi_6Ax5CZU9OlqsZnzTrpHLJVydTllPbnU3AwYQxzimm9Xuxr6_tV3y_qUuj6LNjLJ3kRjVMxRaXyNPJm00) Here I add a function in the interface, but assuming we can implement it at this level (default implementation in Java). If it is not the case, you can have this function somewhere else out of this architecture. It would take the source `Settings` in argument and return the new one after filling it.
Author
Owner

@shanew1694 commented on GitHub (Jan 16, 2024):

Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent

@shanew1694 commented on GitHub (Jan 16, 2024): Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent
Author
Owner

@kpupp commented on GitHub (Jul 23, 2024):

Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent

Definitely the only one that keeps me coming back to Deluge. Having seen it been waffled and hemmed and hawed and hmm'd and closed and reopened and reimagined and waffled over for years (in #590 and #5222), it'd be great to finally include it... Especially with 5.0 lurking around the corner it seems.

@kpupp commented on GitHub (Jul 23, 2024): > Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent Definitely the only one that keeps me coming back to Deluge. Having seen it been waffled and hemmed and hawed and hmm'd and closed and reopened and reimagined and waffled over for years (in #590 and #5222), it'd be great to finally include it... Especially with 5.0 lurking around the corner it seems.
Author
Owner

@AdamT20054 commented on GitHub (Jul 26, 2024):

Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent

Definitely the only one that keeps me coming back to Deluge. Having seen it been waffled and hemmed and hawed and hmm'd and closed and reopened and reimagined and waffled over for years (in #590 and #5222), it'd be great to finally include it... Especially with 5.0 lurking around the corner it seems.

Completely agree.

It's a borderline basic feature.For those who use both public and private trackers, we would much prefer different limits for both as ratios/seedtimes might exceed that of another.

@AdamT20054 commented on GitHub (Jul 26, 2024): > > Has development come to an end for this feature? It would be a very nice feature to have. I think it is the only major feature missing from qbittorrent > > Definitely the only one that keeps me coming back to Deluge. Having seen it been waffled and hemmed and hawed and hmm'd and closed and reopened and reimagined and waffled over for years (in #590 and #5222), it'd be great to finally include it... Especially with 5.0 lurking around the corner it seems. Completely agree. It's a borderline basic feature.For those who use both public and private trackers, we would much prefer different limits for both as ratios/seedtimes might exceed that of another.
Author
Owner

@JackyHe398 commented on GitHub (Dec 5, 2025):

It has been 7 year since the issue opened(actually more than 8 if counting in the similar). May i know is this idea still under developed?

@JackyHe398 commented on GitHub (Dec 5, 2025): It has been 7 year since the issue opened(actually more than 8 if counting in the similar). May i know is this idea still under developed?
Author
Owner

@kpupp commented on GitHub (Dec 5, 2025):

I had wondered about this again the other day too. Not to spam the comment
chain and maintainers but I dearly hope it is. One of the few features
keeping qbit from being on par with (and far exceeding imo) its peers.

On Fri, Dec 5, 2025, 5:39 PM Jacky He @.***> wrote:

JackyHe398 left a comment (qbittorrent/qBittorrent#9939)
https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-3618967478

It has been 7 year since the issue opened(actually more than 8 if counting
in the similar). May i know is this idea still under developed?


Reply to this email directly, view it on GitHub
https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-3618967478,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AZBZMVWZFLNBBB677D44J5T4AIJR7AVCNFSM6AAAAACOGQBIB2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTMMJYHE3DONBXHA
.
You are receiving this because you commented.Message ID:
@.***>

@kpupp commented on GitHub (Dec 5, 2025): I had wondered about this again the other day too. Not to spam the comment chain and maintainers but I dearly hope it is. One of the few features keeping qbit from being on par with (and far exceeding imo) its peers. On Fri, Dec 5, 2025, 5:39 PM Jacky He ***@***.***> wrote: > *JackyHe398* left a comment (qbittorrent/qBittorrent#9939) > <https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-3618967478> > > It has been 7 year since the issue opened(actually more than 8 if counting > in the similar). May i know is this idea still under developed? > > — > Reply to this email directly, view it on GitHub > <https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-3618967478>, > or unsubscribe > <https://github.com/notifications/unsubscribe-auth/AZBZMVWZFLNBBB677D44J5T4AIJR7AVCNFSM6AAAAACOGQBIB2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTMMJYHE3DONBXHA> > . > You are receiving this because you commented.Message ID: > ***@***.***> >
Author
Owner

@matthieu-vergne commented on GitHub (Dec 5, 2025):

Still hoping for it as well. Hopefully my suggestions above can help. I still didn't convert to C++, so still can't help much beside design.

@matthieu-vergne commented on GitHub (Dec 5, 2025): Still hoping for it as well. Hopefully [my suggestions above](https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-1560122674) can help. I still didn't convert to C++, so still can't help much beside design.
Author
Owner

@glassez commented on GitHub (Dec 6, 2025):

Still hoping for it as well. Hopefully my suggestions above can help. I still didn't convert to C++, so still can't help much beside design.

In fact, design has never been a sticking point here. It's just that initially there was a desire to revamp "everything at once", but it turned out to be beyond my strength (I just don't have that much time for this project, besides, most of it is spent on participating in current issues and reviews of other PRs).
But due to the demand for such a feature, I decided to return to this topic, adding a piece at a time.

@glassez commented on GitHub (Dec 6, 2025): > Still hoping for it as well. Hopefully [my suggestions above](https://github.com/qbittorrent/qBittorrent/issues/9939#issuecomment-1560122674) can help. I still didn't convert to C++, so still can't help much beside design. In fact, design has never been a sticking point here. It's just that initially there was a desire to revamp "everything at once", but it turned out to be beyond my strength (I just don't have that much time for this project, besides, most of it is spent on participating in current issues and reviews of other PRs). But due to the demand for such a feature, I decided to return to this topic, adding a piece at a time.
Author
Owner

@glassez commented on GitHub (Dec 6, 2025):

See #23577.

@glassez commented on GitHub (Dec 6, 2025): See #23577.
Author
Owner

@matthieu-vergne commented on GitHub (Dec 6, 2025):

Revamp "everything at once" is never a good idea in practice. Even in huge professional environments, such projects are bound to fail if not strictly planned and organised, and they never fully go the "all at once" route. If time is scarce or uncertainty is high (like wondering what would really fit the bill) agile practices (go one piece at a time) is far more practical. So I can only support that approach. Having a final target is good to drive the effort, but always work it one step after the other.

Hopefully other skilled C++ devs will join you in that effort.

@matthieu-vergne commented on GitHub (Dec 6, 2025): Revamp "everything at once" is never a good idea in practice. Even in huge professional environments, such projects are bound to fail if not strictly planned and organised, and they never fully go the "all at once" route. If time is scarce or uncertainty is high (like wondering what would really fit the bill) agile practices (go one piece at a time) is far more practical. So I can only support that approach. Having a final target is good to drive the effort, but always work it one step after the other. Hopefully other skilled C++ devs will join you in that effort.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/qBittorrent#8121
No description provided.