Skip to content

Commit

Permalink
Ensure the network is connected. (#26)
Browse files Browse the repository at this point in the history
* created upstream branch

--HG--
branch : upstream

* backported changes to upstream

--HG--
branch : upstream

* fixed a typo, now the sync option should work properly

--HG--
branch : upstream

* backported changes to upstream

--HG--
branch : upstream

* Backported to upstream.

--HG--
branch : upstream

* Backported to upstream.

--HG--
branch : upstream

* Backported changes.

--HG--
branch : upstream

* Backported changes to upstream.

--HG--
branch : upstream

* Merged libcurlwrapper and timezone service changes.

--HG--
branch : upstream

* Forgot to add curl-related sources.

--HG--
branch : upstream

* Backported Time Sync changes to upstream.

--HG--
branch : upstream

* Update workflow to use git submodules.

--HG--
branch : upstream

* - Ensure background thread is finished when plugin unloads.
- Updated libwupsxx.

--HG--
branch : upstream

* Changed Makefile to build objects in subdirectories, to avoid conflicts when two different
files in different directories produce the same object file name.

--HG--
branch : upstream

* Ensure the network is initialized before doing network operations.

--HG--
branch : upstream

* Forgot to merge all changes.

--HG--
branch : upstream

* Ensure synchronization task is launched asynchronously.

--HG--
branch : upstream

---------

Co-authored-by: Daniel K. O. (dkosmari) <none@none>
  • Loading branch information
dkosmari and Daniel K. O. (dkosmari) authored Oct 1, 2024
1 parent d97d8e0 commit 5a05063
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 23 deletions.
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

0 comments on commit 5a05063

Please sign in to comment.