Pinning a file should automatically initiate a download to cache #38
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
2025-09-12 10:25:33 -05:00
parent 8475d04341
commit eee5587bab
13 changed files with 129 additions and 22 deletions

View File

@@ -8,7 +8,9 @@
### Issues
* \#33 Complete initial v2.0 documentation
* \#34 Add macOS support
* \#38 Pinning a file should automatically initiate a download to cache
* \#51 [ui] UI console window should close after launch
* \#52 [ui] Add auto-mount on first launch functionality
* \#53 Create Windows installer

View File

@@ -67,6 +67,8 @@ protected:
-> api_error override;
public:
void download() override {}
[[nodiscard]] auto get_source_path() const -> std::string override {
return "direct";
}

View File

@@ -133,6 +133,9 @@ public:
open_file_data ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file) -> api_error;
[[nodiscard]] auto download_pinned_file(const std::string &api_path)
-> bool override;
[[nodiscard]] auto evict_file(const std::string &api_path) -> bool override;
[[nodiscard]] auto get_directory_item(const std::string &api_path,

View File

@@ -31,6 +31,9 @@ class i_file_manager {
INTERFACE_SETUP(i_file_manager);
public:
[[nodiscard]] virtual auto download_pinned_file(const std::string &api_path)
-> bool = 0;
[[nodiscard]] virtual auto evict_file(const std::string &api_path)
-> bool = 0;

View File

@@ -32,6 +32,8 @@ public:
using native_operation_callback = std::function<api_error(native_handle)>;
public:
virtual void download() = 0;
[[nodiscard]] virtual auto get_api_path() const -> std::string = 0;
[[nodiscard]] virtual auto get_chunk_size() const -> std::size_t = 0;
@@ -97,12 +99,12 @@ class i_closeable_open_file : public i_open_file {
public:
virtual void add(std::uint64_t handle, open_file_data ofd) = 0;
[[nodiscard]] virtual auto get_allocated() const -> bool = 0;
[[nodiscard]] virtual auto can_close() const -> bool = 0;
virtual auto close() -> bool = 0;
[[nodiscard]] virtual auto get_allocated() const -> bool = 0;
[[nodiscard]] virtual auto get_handles() const
-> std::vector<std::uint64_t> = 0;

View File

@@ -101,6 +101,8 @@ private:
public:
auto close() -> bool override;
void download() override;
[[nodiscard]] auto get_allocated() const -> bool override;
[[nodiscard]] auto get_read_state() const -> boost::dynamic_bitset<> override;

View File

@@ -43,8 +43,8 @@ public:
ring_buffer_open_file() = delete;
ring_buffer_open_file(const ring_buffer_open_file &) noexcept = delete;
ring_buffer_open_file(ring_buffer_open_file &&) noexcept = delete;
auto operator=(ring_buffer_open_file &&) noexcept -> ring_buffer_open_file & =
delete;
auto operator=(ring_buffer_open_file &&) noexcept
-> ring_buffer_open_file & = delete;
auto operator=(const ring_buffer_open_file &) noexcept
-> ring_buffer_open_file & = delete;
@@ -57,14 +57,14 @@ private:
protected:
[[nodiscard]] auto on_check_start() -> bool override;
[[nodiscard]] auto
on_chunk_downloaded(std::size_t chunk,
const data_buffer &buffer) -> api_error override;
[[nodiscard]] auto on_chunk_downloaded(std::size_t chunk,
const data_buffer &buffer)
-> api_error override;
[[nodiscard]] auto
on_read_chunk(std::size_t chunk, std::size_t read_size,
std::uint64_t read_offset, data_buffer &data,
std::size_t &bytes_read) -> api_error override;
[[nodiscard]] auto on_read_chunk(std::size_t chunk, std::size_t read_size,
std::uint64_t read_offset, data_buffer &data,
std::size_t &bytes_read)
-> api_error override;
[[nodiscard]] auto use_buffer(std::size_t chunk,
std::function<api_error(data_buffer &)> func)
@@ -75,8 +75,10 @@ public:
std::size_t chunk_size,
std::size_t ring_size) -> bool;
[[nodiscard]] auto
native_operation(native_operation_callback callback) -> api_error override;
void download() override {}
[[nodiscard]] auto native_operation(native_operation_callback callback)
-> api_error override;
[[nodiscard]] auto native_operation(std::uint64_t /* new_file_size */,
native_operation_callback /* callback */)

View File

@@ -211,8 +211,7 @@ public:
-> api_error override;
[[nodiscard]] auto set_item_meta(const std::string &api_path,
const api_meta_map &meta)
-> api_error override;
api_meta_map meta) -> api_error override;
[[nodiscard]] auto start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool override;

View File

@@ -230,7 +230,7 @@ public:
}
[[nodiscard]] auto set_item_meta(const std::string & /*api_path*/,
const api_meta_map & /*meta*/)
api_meta_map /*meta*/)
-> api_error override {
return api_error::success;
}

View File

@@ -148,8 +148,7 @@ public:
-> api_error = 0;
[[nodiscard]] virtual auto set_item_meta(const std::string &api_path,
const api_meta_map &meta)
-> api_error = 0;
api_meta_map meta) -> api_error = 0;
[[nodiscard]] virtual auto start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool = 0;

View File

@@ -151,6 +151,58 @@ auto file_manager::create(const std::string &api_path, api_meta_map &meta,
return open(api_path, false, ofd, handle, file);
}
auto download_pinned_file(const std::string &api_path) -> bool {
REPERTORY_USES_FUNCTION_NAME();
recur_mutex_lock file_lock(open_file_mtx_);
try {
if (provider_.is_read_only()) {
return false;
}
auto res = provider_.get_file_meta(api_path, META_PINNED, str_pinned);
if (res != api_error::success) {
return false;
}
if (not utils::string::to_bool(str_pinned)) {
return false;
}
std::uint64_t handle{REPERTORY_INVALID_HANDLE};
std::shared_ptr<i_open_file> open_file;
if (open_file_lookup_.contains(api_path)) {
auto closeable_file = open_file_lookup_.at(api_path);
if (not get_open_file(closeable_file->get_handles().at(0U), true,
open_file)) {
return false;
}
} else {
res = open(api_path, false, {}, handle);
if (res != api_error::success) {
return false;
}
if (not get_open_file(handle, true, open_file)) {
close(handle);
return false;
}
}
open_file.download();
if (handle != REPERTORY_INVALID_HANDLE) {
close(handle);
}
return true;
} catch (const std::exception &ex) {
utils::error::raise_api_path_error(function_name, api_path, ex,
"failed to download pinned file");
}
return false;
}
auto file_manager::evict_file(const std::string &api_path) -> bool {
REPERTORY_USES_FUNCTION_NAME();
@@ -904,7 +956,7 @@ void file_manager::start() {
queue_upload(entry.api_path, entry.source_path, false);
}
for (const auto &entry : mgr_db_->get_resume_list()) {
for (const auto &entry : get_stored_downloads()) {
try {
filesystem_item fsi{};
auto res = provider_.get_filesystem_item(entry.api_path, false, fsi);
@@ -953,6 +1005,8 @@ void file_manager::start() {
: 0U,
fsi, provider_, entry.read_state, *this);
open_file_lookup_[entry.api_path] = closeable_file;
closeable_file.download();
event_system::instance().raise<download_restored>(
fsi.api_path, fsi.source_path, function_name);
} catch (const std::exception &ex) {
@@ -960,6 +1014,11 @@ void file_manager::start() {
}
}
for (const auto &api_path : provider_.get_pinned_files()) {
if (not download_pinned_file(api_path)) {
}
}
upload_thread_ = std::make_unique<std::thread>([this] { upload_handler(); });
event_system::instance().raise<service_start_end>(function_name,
"file_manager");

View File

@@ -90,6 +90,7 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
read_state_ = read_state.value();
set_modified();
allocated = true;
update_reader(0U);
return;
}
@@ -272,6 +273,14 @@ auto open_file::close() -> bool {
return true;
}
void open_file::download() {
unique_recur_mutex_lock rw_lock(rw_mtx_);
auto read_chunk = read_chunk_;
rw_lock.unlock();
update_reader(read_chunk);
}
void open_file::download_chunk(std::size_t chunk, bool skip_active,
bool should_reset) {
REPERTORY_USES_FUNCTION_NAME();

View File

@@ -831,12 +831,37 @@ void base_provider::remove_unmatched_source_files(stop_type &stop_requested) {
auto base_provider::set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) -> api_error {
return meta_db_->set_item_meta(api_path, key, value);
auto ret = meta_db_->set_item_meta(api_path, key, value);
if (ret != api_error::success) {
return ret;
}
if (key == META_PINNED && utils::string::to_bool(value)) {
if (fm_ == nullptr || not fm_->download_pinned_file(api_path)) {
// TODO handle error
}
}
return ret;
}
auto base_provider::set_item_meta(const std::string &api_path,
const api_meta_map &meta) -> api_error {
return meta_db_->set_item_meta(api_path, meta);
api_meta_map meta) -> api_error {
if (meta.contains(META_PINNED)) {
auto res = set_item_meta(api_path, META_PINNED, meta.at(META_PINNED));
if (res != api_error::success) {
return res;
}
meta.erase(META_PINNED);
}
auto ret = meta_db_->set_item_meta(api_path, meta);
if (ret != api_error::success) {
return ret;
}
return ret;
}
auto base_provider::start(api_item_added_callback api_item_added,