[Option][GUI] Upload speed boost
This commit is contained in:
parent
3d90deb16c
commit
61efca5f91
7 changed files with 113 additions and 12 deletions
|
|
@ -45,6 +45,13 @@
|
||||||
"ktg_fonts_use_system_font": "Use system font",
|
"ktg_fonts_use_system_font": "Use system font",
|
||||||
"ktg_fonts_use_original_metrics": "Use Open Sans height",
|
"ktg_fonts_use_original_metrics": "Use Open Sans height",
|
||||||
"ktg_settings_network": "Network",
|
"ktg_settings_network": "Network",
|
||||||
|
"ktg_settings_net_speed_boost": "Upload speed boost",
|
||||||
|
"ktg_net_speed_boost_title": "Upload speed boost",
|
||||||
|
"ktg_net_speed_boost_desc": "Warning: changing this parameter to high values on slow networks can make even worse. Use at your own risk.\n\nYou'll need to restart app to save changes.",
|
||||||
|
"ktg_net_speed_boost_default": "Disabled",
|
||||||
|
"ktg_net_speed_boost_slight": "Slight",
|
||||||
|
"ktg_net_speed_boost_medium": "Medium",
|
||||||
|
"ktg_net_speed_boost_big": "Big",
|
||||||
"ktg_settings_system": "System",
|
"ktg_settings_system": "System",
|
||||||
"ktg_settings_other": "Other",
|
"ktg_settings_other": "Other",
|
||||||
"ktg_profile_copy_id": "Copy ID",
|
"ktg_profile_copy_id": "Copy ID",
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,25 @@ CheckHandler IntLimitMin(int min) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CheckHandler NetSpeedBoostConv(CheckHandler wrapped = nullptr) {
|
||||||
|
return [=] (QVariant value) -> QVariant {
|
||||||
|
auto newValue = 0;
|
||||||
|
if (value.canConvert<int>()) {
|
||||||
|
newValue = value.value<int>();
|
||||||
|
} else if (value.canConvert<QString>()) {
|
||||||
|
const auto strValue = value.value<QString>();
|
||||||
|
if (strValue == "high") {
|
||||||
|
newValue = 3;
|
||||||
|
} else if (strValue == "medium") {
|
||||||
|
newValue = 2;
|
||||||
|
} else if (strValue == "low") {
|
||||||
|
newValue = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (wrapped) ? wrapped(newValue) : newValue;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct Definition {
|
struct Definition {
|
||||||
SettingScope scope = SettingScope::Global;
|
SettingScope scope = SettingScope::Global;
|
||||||
SettingStorage storage = SettingStorage::MainJson;
|
SettingStorage storage = SettingStorage::MainJson;
|
||||||
|
|
@ -267,6 +286,10 @@ const std::map<QString, Definition, std::greater<QString>> DefinitionMap {
|
||||||
.type = SettingType::IntSetting,
|
.type = SettingType::IntSetting,
|
||||||
.defaultValue = 2,
|
.defaultValue = 2,
|
||||||
.limitHandler = IntLimit(0, 2, 2), }},
|
.limitHandler = IntLimit(0, 2, 2), }},
|
||||||
|
{ "net_speed_boost", {
|
||||||
|
.type = SettingType::IntSetting,
|
||||||
|
.defaultValue = 0,
|
||||||
|
.limitHandler = NetSpeedBoostConv(IntLimit(0, 3)), }},
|
||||||
};
|
};
|
||||||
|
|
||||||
using OldOptionKey = QString;
|
using OldOptionKey = QString;
|
||||||
|
|
@ -412,6 +435,7 @@ QByteArray GenerateSettingsJson(bool areDefault = false) {
|
||||||
|
|
||||||
if (areDefault) {
|
if (areDefault) {
|
||||||
settings.insert(qsl("version"), QString::number(AppKotatoVersion));
|
settings.insert(qsl("version"), QString::number(AppKotatoVersion));
|
||||||
|
settings.insert(qsl("net_speed_boost"), QJsonValue(QJsonValue::Null));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto document = QJsonDocument();
|
auto document = QJsonDocument();
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,26 @@ namespace Settings {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
QString NetBoostLabel(int boost) {
|
||||||
|
switch (boost) {
|
||||||
|
case 0:
|
||||||
|
return ktr("ktg_net_speed_boost_default");
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return ktr("ktg_net_speed_boost_slight");
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return ktr("ktg_net_speed_boost_medium");
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return ktr("ktg_net_speed_boost_big");
|
||||||
|
|
||||||
|
default:
|
||||||
|
Unexpected("Boost in Settings::NetBoostLabel.");
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
QString ChatIdLabel(int option) {
|
QString ChatIdLabel(int option) {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -222,6 +242,37 @@ void SetupKotatoNetwork(not_null<Ui::VerticalLayout*> container) {
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
AddSubsectionTitle(container, rktr("ktg_settings_network"));
|
AddSubsectionTitle(container, rktr("ktg_settings_network"));
|
||||||
|
|
||||||
|
const auto netBoostButton = container->add(
|
||||||
|
object_ptr<Button>(
|
||||||
|
container,
|
||||||
|
rktr("ktg_settings_net_speed_boost"),
|
||||||
|
st::settingsButtonNoIcon));
|
||||||
|
auto netBoostText = rpl::single(
|
||||||
|
NetBoostLabel(::Kotato::JsonSettings::GetIntWithPending("net_speed_boost"))
|
||||||
|
) | rpl::then(
|
||||||
|
::Kotato::JsonSettings::EventsWithPending(
|
||||||
|
"net_speed_boost"
|
||||||
|
) | rpl::map([] {
|
||||||
|
return NetBoostLabel(::Kotato::JsonSettings::GetIntWithPending("net_speed_boost"));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
CreateRightLabel(
|
||||||
|
netBoostButton,
|
||||||
|
std::move(netBoostText),
|
||||||
|
st::settingsButtonNoIcon,
|
||||||
|
rktr("ktg_settings_net_speed_boost"));
|
||||||
|
netBoostButton->addClickHandler([=] {
|
||||||
|
Ui::show(Box<::Kotato::RadioBox>(
|
||||||
|
ktr("ktg_net_speed_boost_title"),
|
||||||
|
ktr("ktg_net_speed_boost_desc"),
|
||||||
|
::Kotato::JsonSettings::GetIntWithPending("net_speed_boost"),
|
||||||
|
4,
|
||||||
|
NetBoostLabel,
|
||||||
|
[=] (int value) {
|
||||||
|
::Kotato::JsonSettings::SetAfterRestart("net_speed_boost", value);
|
||||||
|
::Kotato::JsonSettings::Write();
|
||||||
|
}, true));
|
||||||
|
});
|
||||||
|
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "mtproto/dedicated_file_loader.h"
|
#include "mtproto/dedicated_file_loader.h"
|
||||||
|
|
||||||
|
#include "kotato/kotato_settings.h"
|
||||||
#include "mtproto/facade.h"
|
#include "mtproto/facade.h"
|
||||||
#include "main/main_account.h" // Account::sessionChanges.
|
#include "main/main_account.h" // Account::sessionChanges.
|
||||||
#include "main/main_session.h" // Session::account.
|
#include "main/main_session.h" // Session::account.
|
||||||
|
|
@ -80,6 +81,11 @@ std::optional<DedicatedLoader::File> ParseFile(
|
||||||
return DedicatedLoader::File{ name, size, fields.vdc_id().v, location };
|
return DedicatedLoader::File{ name, size, fields.vdc_id().v, location };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RequestCount() {
|
||||||
|
static const auto count = 2 + (2 * ::Kotato::JsonSettings::GetInt("net_speed_boost"));
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
WeakInstance::WeakInstance(base::weak_ptr<Main::Session> session)
|
WeakInstance::WeakInstance(base::weak_ptr<Main::Session> session)
|
||||||
|
|
@ -310,7 +316,7 @@ void DedicatedLoader::startLoading() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedLoader::sendRequest() {
|
void DedicatedLoader::sendRequest() {
|
||||||
if (_requests.size() >= kRequestsCount || _offset >= _size) {
|
if (_requests.size() >= RequestCount() || _offset >= _size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto offset = _offset;
|
const auto offset = _offset;
|
||||||
|
|
@ -326,7 +332,7 @@ void DedicatedLoader::sendRequest() {
|
||||||
MTP::updaterDcId(_dcId));
|
MTP::updaterDcId(_dcId));
|
||||||
_offset += kChunkSize;
|
_offset += kChunkSize;
|
||||||
|
|
||||||
if (_requests.size() < kRequestsCount) {
|
if (_requests.size() < RequestCount()) {
|
||||||
base::call_delayed(kNextRequestDelay, this, [=] { sendRequest(); });
|
base::call_delayed(kNextRequestDelay, this, [=] { sendRequest(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ constexpr ShiftedDcId groupCallStreamDcId(DcId dcId) {
|
||||||
|
|
||||||
constexpr auto kUploadSessionsCount = 2;
|
constexpr auto kUploadSessionsCount = 2;
|
||||||
|
|
||||||
|
constexpr auto kUploadSessionsCountMax = 8;
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
constexpr ShiftedDcId downloadDcId(DcId dcId, int index) {
|
constexpr ShiftedDcId downloadDcId(DcId dcId, int index) {
|
||||||
|
|
@ -92,7 +94,7 @@ inline DcId getTemporaryIdFromRealDcId(ShiftedDcId shiftedDcId) {
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
|
constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
|
||||||
static_assert(kUploadSessionsCount < kMaxMediaDcCount, "Too large MTPUploadSessionsCount!");
|
static_assert(kUploadSessionsCountMax < kMaxMediaDcCount, "Too large MTPUploadSessionsCount!");
|
||||||
return ShiftDcId(dcId, kBaseUploadDcShift + index);
|
return ShiftDcId(dcId, kBaseUploadDcShift + index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -101,14 +103,14 @@ constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
|
||||||
// send(req, callbacks, MTP::uploadDcId(index)) - for upload shifted dc id
|
// send(req, callbacks, MTP::uploadDcId(index)) - for upload shifted dc id
|
||||||
// uploading always to the main dc so BareDcId(result) == 0
|
// uploading always to the main dc so BareDcId(result) == 0
|
||||||
inline ShiftedDcId uploadDcId(int index) {
|
inline ShiftedDcId uploadDcId(int index) {
|
||||||
Expects(index >= 0 && index < kUploadSessionsCount);
|
Expects(index >= 0 && index < kUploadSessionsCountMax);
|
||||||
|
|
||||||
return details::uploadDcId(0, index);
|
return details::uploadDcId(0, index);
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool isUploadDcId(ShiftedDcId shiftedDcId) {
|
constexpr bool isUploadDcId(ShiftedDcId shiftedDcId) {
|
||||||
return (shiftedDcId >= details::uploadDcId(0, 0))
|
return (shiftedDcId >= details::uploadDcId(0, 0))
|
||||||
&& (shiftedDcId < details::uploadDcId(0, kUploadSessionsCount - 1) + kDcShift);
|
&& (shiftedDcId < details::uploadDcId(0, kUploadSessionsCountMax - 1) + kDcShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ShiftedDcId destroyKeyNextDcId(ShiftedDcId shiftedDcId) {
|
inline ShiftedDcId destroyKeyNextDcId(ShiftedDcId shiftedDcId) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
|
|
||||||
|
#include "kotato/kotato_settings.h"
|
||||||
#include "api/api_editing.h"
|
#include "api/api_editing.h"
|
||||||
#include "api/api_send_progress.h"
|
#include "api/api_send_progress.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
|
|
@ -56,6 +57,16 @@ constexpr auto kKillSessionTimeout = 15 * crl::time(000);
|
||||||
return Core::IsMimeSticker(mime) ? "WEBP" : "JPG";
|
return Core::IsMimeSticker(mime) ? "WEBP" : "JPG";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int UploadSessionsCount() {
|
||||||
|
static const auto count = 2 + (2 * ::Kotato::JsonSettings::GetInt("net_speed_boost"));
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UploadSessionsInterval() {
|
||||||
|
static const auto interval = 500 - (100 * ::Kotato::JsonSettings::GetInt("net_speed_boost"));
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct Uploader::File {
|
struct Uploader::File {
|
||||||
|
|
@ -366,7 +377,7 @@ void Uploader::currentFailed() {
|
||||||
dcMap.clear();
|
dcMap.clear();
|
||||||
uploadingId = FullMsgId();
|
uploadingId = FullMsgId();
|
||||||
sentSize = 0;
|
sentSize = 0;
|
||||||
for (int i = 0; i < MTP::kUploadSessionsCount; ++i) {
|
for (int i = 0; i < UploadSessionsCount(); ++i) {
|
||||||
sentSizes[i] = 0;
|
sentSizes[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,13 +404,13 @@ void Uploader::notifyFailed(FullMsgId id, const File &file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uploader::stopSessions() {
|
void Uploader::stopSessions() {
|
||||||
for (int i = 0; i < MTP::kUploadSessionsCount; ++i) {
|
for (int i = 0; i < UploadSessionsCount(); ++i) {
|
||||||
_api->instance().stopSession(MTP::uploadDcId(i));
|
_api->instance().stopSession(MTP::uploadDcId(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uploader::sendNext() {
|
void Uploader::sendNext() {
|
||||||
if (sentSize >= kMaxUploadFileParallelSize || _pausedId.msg) {
|
if (sentSize >= (UploadSessionsCount() * 512 * 1024) || _pausedId.msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,7 +435,7 @@ void Uploader::sendNext() {
|
||||||
auto &uploadingData = i->second;
|
auto &uploadingData = i->second;
|
||||||
|
|
||||||
auto todc = 0;
|
auto todc = 0;
|
||||||
for (auto dc = 1; dc != MTP::kUploadSessionsCount; ++dc) {
|
for (auto dc = 1; dc != UploadSessionsCount(); ++dc) {
|
||||||
if (sentSizes[dc] < sentSizes[todc]) {
|
if (sentSizes[dc] < sentSizes[todc]) {
|
||||||
todc = dc;
|
todc = dc;
|
||||||
}
|
}
|
||||||
|
|
@ -617,7 +628,7 @@ void Uploader::sendNext() {
|
||||||
|
|
||||||
parts.erase(part);
|
parts.erase(part);
|
||||||
}
|
}
|
||||||
_nextTimer.callOnce(kUploadRequestInterval);
|
_nextTimer.callOnce(crl::time(UploadSessionsInterval()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uploader::cancel(const FullMsgId &msgId) {
|
void Uploader::cancel(const FullMsgId &msgId) {
|
||||||
|
|
@ -674,7 +685,7 @@ void Uploader::clear() {
|
||||||
cancelRequests();
|
cancelRequests();
|
||||||
dcMap.clear();
|
dcMap.clear();
|
||||||
sentSize = 0;
|
sentSize = 0;
|
||||||
for (int i = 0; i < MTP::kUploadSessionsCount; ++i) {
|
for (int i = 0; i < UploadSessionsCount(); ++i) {
|
||||||
_api->instance().stopSession(MTP::uploadDcId(i));
|
_api->instance().stopSession(MTP::uploadDcId(i));
|
||||||
sentSizes[i] = 0;
|
sentSizes[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ private:
|
||||||
base::flat_map<mtpRequestId, int32> docRequestsSent;
|
base::flat_map<mtpRequestId, int32> docRequestsSent;
|
||||||
base::flat_map<mtpRequestId, int32> dcMap;
|
base::flat_map<mtpRequestId, int32> dcMap;
|
||||||
uint32 sentSize = 0; // FileSize: Right now any file size fits 32 bit.
|
uint32 sentSize = 0; // FileSize: Right now any file size fits 32 bit.
|
||||||
uint32 sentSizes[MTP::kUploadSessionsCount] = { 0 };
|
uint32 sentSizes[MTP::kUploadSessionsCountMax] = { 0 };
|
||||||
|
|
||||||
FullMsgId uploadingId;
|
FullMsgId uploadingId;
|
||||||
FullMsgId _pausedId;
|
FullMsgId _pausedId;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue