Skip to content

Commit

Permalink
feat(daemon): pick up cached packages while sync
Browse files Browse the repository at this point in the history
- Makes sync cache structure randomless (remove uuid usage)
- Moves validation logic closer to download logic
- Checks if file is already downloaded and valid and uses it in that case
- Removes obsolete PackageFile.h

Fixes anydistro#44
  • Loading branch information
LordTermor committed May 27, 2024
1 parent 9afe92d commit c9f8d28
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 79 deletions.
32 changes: 0 additions & 32 deletions daemon/infrastructure/PackageFile.h

This file was deleted.

87 changes: 45 additions & 42 deletions daemon/infrastructure/alpm/ArchRepoSyncService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
#include "utilities/alpmdb/Desc.h"
#include "utilities/libarchive/Reader.h"
#include "utilities/log/Logging.h"
#include "utilities/to_string.h"

#include <boost/uuid/uuid_io.hpp>
#include <coro/sync_wait.hpp>
#include <coro/thread_pool.hpp>
#include <coro/when_all.hpp>
Expand Down Expand Up @@ -120,25 +120,9 @@ coro::task<SyncService::Result<std::vector<Package>>>
std::move(remote_packages.error()), SyncError::NetworkError);
}

const auto uuid = boost::uuids::random_generator()();

auto task = [this, section, uuid](const auto pkgname)
-> coro::task<ArchRepoSyncService::Result<Package>> {
auto package_file = co_await download_package(section, pkgname, uuid);

if (!package_file) { co_return std::unexpected(package_file.error()); }

auto package_result = Package::from_file_path(
SectionDTOMapper::to_entity(package_file->section()),
Core::Domain::PoolLocation::Sync, package_file->file_path());

if (!package_result.has_value()) {
co_return bxt::make_error_with_source<DownloadError>(
std::move(package_result.error()), package_file->file_path(),
"Parse error");
}

co_return *package_result;
auto task = [this,
section](const auto pkgname) -> coro::task<Result<Package>> {
co_return co_await download_package(section, pkgname);
};

auto tasks = *remote_packages | std::views::transform(task)
Expand Down Expand Up @@ -279,10 +263,9 @@ coro::task<ArchRepoSyncService::Result<std::vector<std::string>>>
co_return result;
}

coro::task<ArchRepoSyncService::Result<PackageFile>>
coro::task<ArchRepoSyncService::Result<Package>>
ArchRepoSyncService::download_package(PackageSectionDTO section,
std::string package_filename,
boost::uuids::uuid id) {
std::string package_filename) {
const auto repository_name =
m_options.sources[section].repo_name.value_or(section.repository);

Expand All @@ -295,36 +278,46 @@ coro::task<ArchRepoSyncService::Result<PackageFile>>
fmt::arg("architecture", section.architecture),
fmt::arg("pkgfname", package_filename));

const auto filepath = m_options.sources[section].download_path
/ std::string(boost::uuids::to_string(id));
const auto filepath =
m_options.sources[section].download_path / bxt::to_string(section);

std::error_code ec;
if (std::filesystem::create_directories(filepath, ec); ec) {
co_return bxt::make_error<DownloadError>(
package_filename, "Cannot create directory: " + ec.message());
}

const auto full_filename =
fmt::format("{}/{}", filepath.string(), package_filename);
const auto full_filename = filepath / package_filename;

if (std::filesystem::exists(full_filename)) {
co_return PackageFile(section, full_filename);
}

auto response = co_await download_file(m_options.sources[section].repo_url,
path, full_filename);
logi("Found package file in local cache: {}", full_filename);
auto package = Package::from_file_path(
SectionDTOMapper::to_entity(section),
Core::Domain::PoolLocation::Sync, full_filename);

if (!response.has_value()) {
co_return bxt::make_error<DownloadError>(package_filename,
"Can't download the package");
}
if (!(*response)) {
co_return bxt::make_error<DownloadError>(
package_filename, httplib::to_string(response->error()));
if (!package.has_value()) {
logw("Invalid package file: {}, removing it", full_filename);
std::filesystem::remove(full_filename);
} else {
logi("Using local cache package file: {}", full_filename);
}
}
if (!std::filesystem::exists(full_filename)) {
auto response = co_await download_file(
m_options.sources[section].repo_url, path, full_filename);

response = co_await download_file(m_options.sources[section].repo_url,
path + ".sig", full_filename + ".sig");
if (!response.has_value()) {
co_return bxt::make_error<DownloadError>(
package_filename, "Can't download the package");
}
if (!(*response)) {
co_return bxt::make_error<DownloadError>(
package_filename, httplib::to_string(response->error()));
}
}
auto response =
co_await download_file(m_options.sources[section].repo_url,
path + ".sig", full_filename + ".sig");

if (!response.has_value()) {
co_return bxt::make_error<DownloadError>(
Expand All @@ -335,7 +328,17 @@ coro::task<ArchRepoSyncService::Result<PackageFile>>
package_filename + ".sig", httplib::to_string(response->error()));
}

co_return PackageFile(section, full_filename);
auto result = Package::from_file_path(SectionDTOMapper::to_entity(section),
Core::Domain::PoolLocation::Sync,
full_filename);

if (result.has_value()) {
co_return result.value();
} else {
co_return bxt::make_error_with_source<DownloadError>(
std::move(result.error()), package_filename,
"Can't parse the package");
}
}
coro::task<std::optional<httplib::Result>> ArchRepoSyncService::download_file(
std::string url, std::string path, std::string filename) {
Expand Down
8 changes: 3 additions & 5 deletions daemon/infrastructure/alpm/ArchRepoSyncService.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

#include "ArchRepoOptions.h"
#include "core/application/services/SyncService.h"
#include "core/domain/entities/Package.h"
#include "core/domain/repositories/PackageRepositoryBase.h"
#include "infrastructure/PackageFile.h"
#include "utilities/Error.h"
#include "utilities/eventbus/EventBusDispatcher.h"

Expand Down Expand Up @@ -54,10 +54,8 @@ class ArchRepoSyncService : public bxt::Core::Application::SyncService {

coro::task<Result<std::vector<std::string>>>
get_available_packages(const PackageSectionDTO section);
coro::task<Result<PackageFile>>
download_package(PackageSectionDTO section,
std::string package_filename,
boost::uuids::uuid id);
coro::task<Result<Package>> download_package(PackageSectionDTO section,
std::string package_filename);

coro::task<std::unique_ptr<httplib::SSLClient>>
get_client(const std::string url);
Expand Down

0 comments on commit c9f8d28

Please sign in to comment.