Skip to content

Commit 6710c2b

Browse files
committed
teepod-ui: Add pagination/search and optimize net traffic
1 parent 9ded6f8 commit 6710c2b

File tree

4 files changed

+494
-84
lines changed

4 files changed

+494
-84
lines changed

teepod/rpc/proto/teepod_rpc.proto

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,27 @@ message UpgradeAppRequest {
104104
repeated PortMapping ports = 7;
105105
}
106106

107-
// Message for VM list response
107+
// Message for Status request
108+
message StatusRequest {
109+
// List of VM IDs
110+
repeated string ids = 1;
111+
// Brief (Don't include VM configuration)
112+
bool brief = 2;
113+
// Filter by keyword
114+
string keyword = 3;
115+
// Page number
116+
uint32 page = 4;
117+
// Page size
118+
uint32 page_size = 5;
119+
}
120+
108121
message StatusResponse {
109122
// List of VMs
110123
repeated VmInfo vms = 1;
111124
// Port mapping enabled
112125
bool port_mapping_enabled = 2;
126+
// Total number of VMs
127+
uint32 total = 3;
113128
}
114129

115130
message ImageListResponse {
@@ -210,7 +225,7 @@ service Teepod {
210225
rpc ResizeVm(ResizeVmRequest) returns (google.protobuf.Empty);
211226

212227
// RPC to list all VMs
213-
rpc Status(google.protobuf.Empty) returns (StatusResponse);
228+
rpc Status(StatusRequest) returns (StatusResponse);
214229
// RPC to list all available images
215230
rpc ListImages(google.protobuf.Empty) returns (ImageListResponse);
216231

teepod/src/app.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::net::IpAddr;
1616
use std::path::{Path, PathBuf};
1717
use std::sync::{Arc, Mutex, MutexGuard};
1818
use supervisor_client::SupervisorClient;
19-
use teepod_rpc::{self as pb, GpuInfo, VmConfiguration};
19+
use teepod_rpc::{self as pb, GpuInfo, StatusRequest, StatusResponse, VmConfiguration};
2020
use tracing::{error, info};
2121

2222
pub use image::{Image, ImageInfo};
@@ -306,7 +306,7 @@ impl App {
306306
Ok(())
307307
}
308308

309-
pub async fn list_vms(&self) -> Result<Vec<pb::VmInfo>> {
309+
pub async fn list_vms(&self, request: StatusRequest) -> Result<StatusResponse> {
310310
let vms = self
311311
.supervisor
312312
.list()
@@ -319,6 +319,19 @@ impl App {
319319
let mut infos = self
320320
.lock()
321321
.iter_vms()
322+
.filter(|vm| {
323+
if !request.ids.is_empty() && !request.ids.contains(&vm.config.manifest.id) {
324+
return false;
325+
}
326+
if request.keyword.is_empty() {
327+
true
328+
} else {
329+
vm.config.manifest.name.contains(&request.keyword)
330+
|| vm.config.manifest.id.contains(&request.keyword)
331+
|| vm.config.manifest.app_id.contains(&request.keyword)
332+
|| vm.config.manifest.image.contains(&request.keyword)
333+
}
334+
})
322335
.map(|vm| {
323336
vm.merged_info(
324337
vms.get(&vm.config.manifest.id),
@@ -328,10 +341,17 @@ impl App {
328341
.collect::<Vec<_>>();
329342

330343
infos.sort_by(|a, b| a.manifest.created_at_ms.cmp(&b.manifest.created_at_ms));
331-
let gw = &self.config.gateway;
332344

333-
let lst = infos.into_iter().map(|info| info.to_pb(gw)).collect();
334-
Ok(lst)
345+
let total = infos.len() as u32;
346+
347+
infos = paginate(infos, request.page, request.page_size);
348+
349+
let gw = &self.config.gateway;
350+
Ok(StatusResponse {
351+
vms: infos.into_iter().map(|info| info.to_pb(gw)).collect(),
352+
port_mapping_enabled: self.config.cvm.port_mapping.enabled,
353+
total,
354+
})
335355
}
336356

337357
pub fn list_images(&self) -> Result<Vec<(String, ImageInfo)>> {
@@ -583,6 +603,20 @@ impl App {
583603
}
584604
}
585605

606+
fn paginate<T>(items: Vec<T>, page: u32, page_size: u32) -> Vec<T> {
607+
if page == 0 || page_size == 0 {
608+
return items;
609+
}
610+
let page = page - 1;
611+
let start = page * page_size;
612+
let end = start + page_size;
613+
items
614+
.into_iter()
615+
.skip(start as usize)
616+
.take(end as usize)
617+
.collect()
618+
}
619+
586620
#[derive(Clone)]
587621
pub struct VmState {
588622
pub(crate) config: Arc<VmConfig>,

0 commit comments

Comments
 (0)