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

View File

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

View File

@@ -133,6 +133,9 @@ public:
open_file_data ofd, std::uint64_t &handle, open_file_data ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file) -> api_error; 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 evict_file(const std::string &api_path) -> bool override;
[[nodiscard]] auto get_directory_item(const std::string &api_path, [[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); INTERFACE_SETUP(i_file_manager);
public: public:
[[nodiscard]] virtual auto download_pinned_file(const std::string &api_path)
-> bool = 0;
[[nodiscard]] virtual auto evict_file(const std::string &api_path) [[nodiscard]] virtual auto evict_file(const std::string &api_path)
-> bool = 0; -> bool = 0;

View File

@@ -32,6 +32,8 @@ public:
using native_operation_callback = std::function<api_error(native_handle)>; using native_operation_callback = std::function<api_error(native_handle)>;
public: public:
virtual void download() = 0;
[[nodiscard]] virtual auto get_api_path() const -> std::string = 0; [[nodiscard]] virtual auto get_api_path() const -> std::string = 0;
[[nodiscard]] virtual auto get_chunk_size() const -> std::size_t = 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: public:
virtual void add(std::uint64_t handle, open_file_data ofd) = 0; 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; [[nodiscard]] virtual auto can_close() const -> bool = 0;
virtual auto close() -> bool = 0; virtual auto close() -> bool = 0;
[[nodiscard]] virtual auto get_allocated() const -> bool = 0;
[[nodiscard]] virtual auto get_handles() const [[nodiscard]] virtual auto get_handles() const
-> std::vector<std::uint64_t> = 0; -> std::vector<std::uint64_t> = 0;

View File

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

View File

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

View File

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

View File

@@ -148,8 +148,7 @@ public:
-> api_error = 0; -> api_error = 0;
[[nodiscard]] virtual auto set_item_meta(const std::string &api_path, [[nodiscard]] virtual auto set_item_meta(const std::string &api_path,
const api_meta_map &meta) api_meta_map meta) -> api_error = 0;
-> api_error = 0;
[[nodiscard]] virtual auto start(api_item_added_callback api_item_added, [[nodiscard]] virtual auto start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool = 0; 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); 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 { auto file_manager::evict_file(const std::string &api_path) -> bool {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@@ -904,7 +956,7 @@ void file_manager::start() {
queue_upload(entry.api_path, entry.source_path, false); 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 { try {
filesystem_item fsi{}; filesystem_item fsi{};
auto res = provider_.get_filesystem_item(entry.api_path, false, fsi); auto res = provider_.get_filesystem_item(entry.api_path, false, fsi);
@@ -953,6 +1005,8 @@ void file_manager::start() {
: 0U, : 0U,
fsi, provider_, entry.read_state, *this); fsi, provider_, entry.read_state, *this);
open_file_lookup_[entry.api_path] = closeable_file; open_file_lookup_[entry.api_path] = closeable_file;
closeable_file.download();
event_system::instance().raise<download_restored>( event_system::instance().raise<download_restored>(
fsi.api_path, fsi.source_path, function_name); fsi.api_path, fsi.source_path, function_name);
} catch (const std::exception &ex) { } 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(); }); upload_thread_ = std::make_unique<std::thread>([this] { upload_handler(); });
event_system::instance().raise<service_start_end>(function_name, event_system::instance().raise<service_start_end>(function_name,
"file_manager"); "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(); read_state_ = read_state.value();
set_modified(); set_modified();
allocated = true; allocated = true;
update_reader(0U);
return; return;
} }
@@ -272,6 +273,14 @@ auto open_file::close() -> bool {
return true; 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, void open_file::download_chunk(std::size_t chunk, bool skip_active,
bool should_reset) { bool should_reset) {
REPERTORY_USES_FUNCTION_NAME(); 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, auto base_provider::set_item_meta(const std::string &api_path,
const std::string &key, const std::string &key,
const std::string &value) -> api_error { 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, auto base_provider::set_item_meta(const std::string &api_path,
const api_meta_map &meta) -> api_error { api_meta_map meta) -> api_error {
return meta_db_->set_item_meta(api_path, meta); 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, auto base_provider::start(api_item_added_callback api_item_added,