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
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
This commit is contained in:
@@ -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
|
||||||
|
@@ -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";
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 */)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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");
|
||||||
|
@@ -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();
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user