[pve-devel] [RFC pve-storage 7/7] stats: api: cache storage plugin status
Lukas Wagner
l.wagner at proxmox.com
Mon Aug 21 15:44:44 CEST 2023
Cache storage plugin status so that pvestatd and API calls can use the
cached results, without having to query all storage plugins again.
Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
---
src/PVE/API2/Storage/Config.pm | 10 +++++++++
src/PVE/Storage.pm | 40 ++++++++++++++++++++++++----------
2 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/PVE/API2/Storage/Config.pm b/src/PVE/API2/Storage/Config.pm
index e04b6ab..8c3df99 100755
--- a/src/PVE/API2/Storage/Config.pm
+++ b/src/PVE/API2/Storage/Config.pm
@@ -16,6 +16,7 @@ use PVE::JSONSchema qw(get_standard_option);
use PVE::RPCEnvironment;
use PVE::RESTHandler;
+use PVE::RS::Cache;
use base qw(PVE::RESTHandler);
@@ -274,6 +275,9 @@ __PACKAGE__->register_method ({
die $err;
}
+ # Remove cached plugin status on configuration changes.
+ PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
PVE::Storage::write_config($cfg);
}, "create storage failed");
@@ -373,6 +377,9 @@ __PACKAGE__->register_method ({
." in Proxmox VE 9. Use 'create-base-path' or 'create-subdirs' instead.\n"
}
+ # Remove cached plugin status on configuration changes.
+ PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
PVE::Storage::write_config($cfg);
}, "update storage failed");
@@ -422,6 +429,9 @@ __PACKAGE__->register_method ({
delete $cfg->{ids}->{$storeid};
+ # Remove cached plugin status on configuration changes.
+ PVE::RS::Cache->pvestatd_cache()->delete("storage_plugin_status");
+
PVE::Storage::write_config($cfg);
}, "delete storage failed");
diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm
index a4d85e1..7aa3b2e 100755
--- a/src/PVE/Storage.pm
+++ b/src/PVE/Storage.pm
@@ -23,6 +23,7 @@ use PVE::INotify;
use PVE::RPCEnvironment;
use PVE::SSHInfo;
use PVE::RESTEnvironment qw(log_warn);
+use PVE::RS::Cache;
use PVE::Storage::Plugin;
use PVE::Storage::DirPlugin;
@@ -1276,6 +1277,10 @@ sub storage_info {
my $cache = {};
+ my $status_cache = PVE::RS::Cache->pvestatd_cache();
+ my $cached_status = $status_cache->get("storage_plugin_status");
+ my $refresh_status = !$cached_status;
+
foreach my $storeid (keys %$ids) {
my $scfg = $ids->{$storeid};
@@ -1291,21 +1296,34 @@ sub storage_info {
if $pd->{select_existing};
}
- eval { activate_storage($cfg, $storeid, $cache); };
- if (my $err = $@) {
- warn $err;
- next;
+ if ($refresh_status) {
+ eval { activate_storage($cfg, $storeid, $cache); };
+ if (my $err = $@) {
+ warn $err;
+ next;
+ }
+ $cached_status->{$storeid} = eval { $plugin->status($storeid, $scfg, $cache); };
+
+ my ($total, $avail, $used, $active) = eval { $plugin->status($storeid, $scfg, $cache); };
+ warn $@ if $@;
+ $cached_status->{$storeid} = {};
+
+ $cached_status->{$storeid}->{total} = int($total);
+ $cached_status->{$storeid}->{avail} = int($avail);
+ $cached_status->{$storeid}->{used} = int($used);
+ $cached_status->{$storeid}->{active} = $active;
+ next if !$active;
}
- my ($total, $avail, $used, $active) = eval { $plugin->status($storeid, $scfg, $cache); };
- warn $@ if $@;
- next if !$active;
- $info->{$storeid}->{total} = int($total);
- $info->{$storeid}->{avail} = int($avail);
- $info->{$storeid}->{used} = int($used);
- $info->{$storeid}->{active} = $active;
+ $info->{$storeid}->{total} = $cached_status->{$storeid}->{total};
+ $info->{$storeid}->{avail} = $cached_status->{$storeid}->{avail};
+ $info->{$storeid}->{used} = $cached_status->{$storeid}->{used};
+ $info->{$storeid}->{active} = $cached_status->{$storeid}->{active};
}
+ # TODO: How long should status results be valid?
+ $status_cache->set('storage_plugin_status', $cached_status, 30) if $refresh_status;
+
return $info;
}
--
2.39.2
More information about the pve-devel
mailing list