Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure the network is connected. #26

Merged
merged 30 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7882abc
created upstream branch
Oct 7, 2023
1159cbd
backported changes to upstream
Oct 7, 2023
2d30509
fixed a typo, now the sync option should work properly
Oct 7, 2023
ef8327d
synchronized with upstream
Oct 7, 2023
3d5783a
synchronized with upstream
Oct 10, 2023
de45902
backported changes to upstream
Oct 10, 2023
deaba0c
Backported to upstream.
Oct 12, 2023
c7b208c
Sync with upstream.
Oct 20, 2023
e5a3c19
Backported to upstream.
Oct 20, 2023
96cff43
Syncrhonized with upstream.
Nov 11, 2023
3aa9608
Backported changes.
Nov 11, 2023
3146c7e
Sync with upstream.
May 6, 2024
73de84b
Sync with upstream.
May 30, 2024
8f1c379
Backported changes to upstream.
May 30, 2024
ac98085
Sync with upstream.
Jun 1, 2024
df50058
Synchronized with upstream.
Jun 3, 2024
12119f5
Sync with upstream.
Jun 6, 2024
8b92a0c
Merged libcurlwrapper and timezone service changes.
Jun 6, 2024
4967adc
Forgot to add curl-related sources.
Jun 6, 2024
585e71d
Sync with upstream.
Jun 8, 2024
b2f7719
Sync with upstream.
Sep 12, 2024
258eed9
Backported Time Sync changes to upstream.
Sep 12, 2024
9d8c99c
Update workflow to use git submodules.
Sep 12, 2024
32e98b3
Sync with upstream.
Sep 22, 2024
008243f
- Ensure background thread is finished when plugin unloads.
Sep 22, 2024
d5be6e9
Changed Makefile to build objects in subdirectories, to avoid conflic…
Sep 22, 2024
0daf434
Sync with upstream.
Sep 26, 2024
3519a52
Ensure the network is initialized before doing network operations.
Sep 26, 2024
65ed684
Forgot to merge all changes.
Sep 26, 2024
989ff1d
Ensure synchronization task is launched asynchronously.
Sep 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/synchronize_item.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

struct synchronize_item : wups::config::button_item {

std::future<void> sync_result;
std::stop_source sync_stopper;
std::future<void> task_result;
std::stop_source task_stopper;


synchronize_item();
Expand Down
20 changes: 20 additions & 0 deletions include/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ namespace utils {
std::chrono::minutes>
fetch_timezone(int idx);


// RAII class to ensure network is working.
// It blocks until the network is available, of throws std::runtime_error.
class network_guard {

struct init_guard {
init_guard();
~init_guard();
};

struct connect_guard {
connect_guard();
~connect_guard();
};

init_guard init;
connect_guard conn;

};

} // namespace utils

#endif
2 changes: 0 additions & 2 deletions source/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,8 @@ namespace cfg {
{
logger::initialize(PLUGIN_NAME);

// logger::printf("reloading configs\n");
cfg::reload();

// logger::printf("building config items\n");
root.add(make_config_screen());
root.add(make_preview_screen());
root.add(synchronize_item::create());
Expand Down
2 changes: 2 additions & 0 deletions source/clock_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ clock_item::run()
using std::to_string;
using time_utils::seconds_to_human;

utils::network_guard net_guard;

for (auto& [key, value] : server_infos) {
value.name->text.clear();
value.correction->text.clear();
Expand Down
7 changes: 3 additions & 4 deletions source/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace {
return ticks_to_string(ticks);
}

}
} // namespace


namespace core {
Expand Down Expand Up @@ -291,6 +291,8 @@ namespace core {
{
using time_utils::seconds_to_human;

utils::network_guard net_guard;

// ensure notification is initialized if needed
notify::guard notify_guard{cfg::notify > 0};

Expand Down Expand Up @@ -489,7 +491,4 @@ namespace core {

} // namespace background




} // namespace core
10 changes: 6 additions & 4 deletions source/synchronize_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ synchronize_item::on_started()
{
status_msg = "Synchronizing...";

sync_stopper = {};
task_stopper = {};

auto task = [this](std::stop_token token)
{
Expand All @@ -55,15 +55,17 @@ synchronize_item::on_started()
}
};

sync_result = std::async(task, sync_stopper.get_token());
task_result = std::async(std::launch::async,
std::move(task),
task_stopper.get_token());
}


void
synchronize_item::on_finished()
{
try {
sync_result.get();
task_result.get();
status_msg = "Success!";
cfg::save_important_vars();
}
Expand All @@ -77,5 +79,5 @@ synchronize_item::on_finished()
void
synchronize_item::on_cancel()
{
sync_stopper.request_stop();
task_stopper.request_stop();
}
52 changes: 41 additions & 11 deletions source/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@
#include <iterator> // distance()
#include <stdexcept> // logic_error, runtime_error

#include <nn/ac.h>

#include "utils.hpp"

#include "http_client.hpp"


using namespace std::literals;

using std::logic_error;
using std::runtime_error;


namespace utils {

Expand Down Expand Up @@ -123,17 +128,14 @@ namespace utils {
case 2:
return "https://ipapi.co";
default:
throw std::logic_error{"invalid tz service"};
throw logic_error{"Invalid tz service."};
}
}


std::pair<std::string, std::chrono::minutes>
fetch_timezone(int idx)
{
if (idx < 0 || idx >= num_tz_services)
throw std::logic_error{"invalid service"};

const char* service = get_tz_service_name(idx);

static const char* urls[num_tz_services] = {
Expand All @@ -142,6 +144,8 @@ namespace utils {
"https://ipapi.co/csv"
};

network_guard net_guard;

std::string response = http::get(urls[idx]);

switch (idx) {
Expand All @@ -150,7 +154,7 @@ namespace utils {
{
auto tokens = csv_split(response);
if (size(tokens) != 2)
throw std::runtime_error{"Could not parse response from "s + service};
throw runtime_error{"Could not parse response from "s + service};
std::string name = tokens[0];
auto offset = std::chrono::seconds{std::stoi(tokens[1])};
return {name, duration_cast<std::chrono::minutes>(offset)};
Expand All @@ -163,26 +167,26 @@ namespace utils {
// returned as +HHMM, not seconds.
auto lines = split(response, "\r\n");
if (size(lines) != 2)
throw std::runtime_error{"Could not parse response from "s + service};
throw runtime_error{"Could not parse response from "s + service};

auto keys = csv_split(lines[0]);
auto values = csv_split(lines[1]);
if (size(keys) != size(values))
throw std::runtime_error{"Incoherent response from "s + service};
throw runtime_error{"Incoherent response from "s + service};

auto tz_it = std::ranges::find(keys, "timezone");
auto offset_it = std::ranges::find(keys, "utc_offset");
if (tz_it == keys.end() || offset_it == keys.end())
throw std::runtime_error{"Could not find timezone or utc_offset fields"
" in response."};
throw runtime_error{"Could not find timezone or utc_offset fields"
" in response."};

auto tz_idx = std::distance(keys.begin(), tz_it);;
auto offset_idx = std::distance(keys.begin(), offset_it);

std::string name = values[tz_idx];
std::string hhmm = values[offset_idx];
if (empty(hhmm))
throw std::runtime_error{"Invalid UTC offset string."};
throw runtime_error{"Invalid UTC offset string."};

char sign = hhmm[0];
std::string hh = hhmm.substr(1, 2);
Expand All @@ -196,9 +200,35 @@ namespace utils {
}

default:
throw std::logic_error{"invalid tz service"};
throw logic_error{"Invalid tz service."};
}

}


network_guard::init_guard::init_guard()
{
if (!nn::ac::Initialize())
throw runtime_error{"Network error (nn::ac::Initialize() failed)"};
}


network_guard::init_guard::~init_guard()
{
nn::ac::Finalize();
}


network_guard::connect_guard::connect_guard()
{
if (!nn::ac::Connect())
throw runtime_error{"Network error (nn::ac::Connect() failed)"};
}


network_guard::connect_guard::~connect_guard()
{
nn::ac::Close();
}

} // namespace utils