Skip to content

Commit

Permalink
Extract app into its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
jfernandez committed Feb 19, 2024
1 parent f9a2c3c commit 4d4f5c2
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 92 deletions.
72 changes: 72 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use std::{collections::HashMap, sync::{Arc, Mutex}, thread, time::{Duration, Instant}};

use libbpf_rs::query::ProgInfoIter;
use ratatui::widgets::TableState;

use crate::bpf_program::BpfProgram;

pub struct App {
pub state: TableState,
pub items: Arc<Mutex<Vec<BpfProgram>>>,
}

impl App {
pub fn new() -> App {
App {
state: TableState::default(),
items: Arc::new(Mutex::new(vec![])),
}
}

pub fn start_background_thread(&self) {
let items_clone = Arc::clone(&self.items);

thread::spawn(move || loop {
// Lock items for this thread's exclusive use.
let mut items = items_clone.lock().unwrap();

let items_copy = items.clone();
let map: HashMap<String, &BpfProgram> = items_copy
.iter()
.map(|prog| (prog.id.clone(), prog))
.collect();
items.clear();

let iter = ProgInfoIter::default();
for prog in iter {
let instant = Instant::now();

let prog_name = prog.name.to_str().unwrap().to_string();

if prog_name.is_empty() {
continue;
}

let mut bpf_program = BpfProgram {
id: prog.id.to_string(),
bpf_type: prog.ty.to_string(),
name: prog_name,
prev_runtime_ns: 0,
run_time_ns: prog.run_time_ns,
prev_run_cnt: 0,
run_cnt: prog.run_cnt,
instant,
period_ns: 0,
};

if let Some(prev_bpf_program) = map.get(&bpf_program.id) {
bpf_program.prev_runtime_ns = prev_bpf_program.run_time_ns;
bpf_program.prev_run_cnt = prev_bpf_program.run_cnt;
bpf_program.period_ns = prev_bpf_program.instant.elapsed().as_nanos();
}

items.push(bpf_program);
}

// Explicitly drop the MutexGuard returned by lock() to unlock before sleeping.
drop(items);

thread::sleep(Duration::from_secs(1));
});
}
}
99 changes: 7 additions & 92 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,24 @@
/**
*
* Copyright 2024 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::os::fd::FromRawFd;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::thread;
use std::time::Duration;

use anyhow::{anyhow, Result};
use app::App;
use bpf_program::BpfProgram;
use crossterm::event::{self, poll, Event, KeyCode, KeyModifiers};
use crossterm::execute;
use crossterm::terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
};
use libbpf_rs::query::ProgInfoIter;
use libbpf_sys::bpf_enable_stats;
use ratatui::backend::{Backend, CrosstermBackend};
use ratatui::layout::{Constraint, Layout};
use ratatui::style::{Color, Modifier, Style};
use ratatui::widgets::{Block, Borders, Cell, Row, Table, TableState};
use ratatui::widgets::{Block, Borders, Cell, Row, Table};
use ratatui::{Frame, Terminal};

mod app;
mod bpf_program;

impl From<&BpfProgram> for Row<'_> {
Expand All @@ -57,72 +38,6 @@ impl From<&BpfProgram> for Row<'_> {
}
}

struct App {
state: TableState,
items: Arc<Mutex<Vec<BpfProgram>>>,
}

impl App {
fn new() -> App {
App {
state: TableState::default(),
items: Arc::new(Mutex::new(vec![])),
}
}

pub fn start_background_thread(&self) {
let items_clone = Arc::clone(&self.items);

thread::spawn(move || loop {
// Lock items for this thread's exclusive use.
let mut items = items_clone.lock().unwrap();

let items_copy = items.clone();
let map: HashMap<String, &BpfProgram> = items_copy
.iter()
.map(|prog| (prog.id.clone(), prog))
.collect();
items.clear();

let iter = ProgInfoIter::default();
for prog in iter {
let instant = Instant::now();

let prog_name = prog.name.to_str().unwrap().to_string();

if prog_name.is_empty() {
continue;
}

let mut bpf_program = BpfProgram {
id: prog.id.to_string(),
bpf_type: prog.ty.to_string(),
name: prog_name,
prev_runtime_ns: 0,
run_time_ns: prog.run_time_ns,
prev_run_cnt: 0,
run_cnt: prog.run_cnt,
instant,
period_ns: 0,
};

if let Some(prev_bpf_program) = map.get(&bpf_program.id) {
bpf_program.prev_runtime_ns = prev_bpf_program.run_time_ns;
bpf_program.prev_run_cnt = prev_bpf_program.run_cnt;
bpf_program.period_ns = prev_bpf_program.instant.elapsed().as_nanos();
}

items.push(bpf_program);
}

// Explicitly drop the MutexGuard returned by lock() to unlock before sleeping.
drop(items);

thread::sleep(Duration::from_secs(1));
});
}
}

fn main() -> Result<()> {
if !running_as_root() {
return Err(anyhow!("This program must be run as root"));
Expand All @@ -144,10 +59,10 @@ fn main() -> Result<()> {
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;

// create app and run it
// create app and run the draw loop
let app = App::new();
app.start_background_thread();
let res = run_app(&mut terminal, app);
let res = run_draw_loop(&mut terminal, app);

// // restore terminal
disable_raw_mode()?;
Expand All @@ -162,7 +77,7 @@ fn main() -> Result<()> {
Ok(())
}

fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> Result<()> {
fn run_draw_loop<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> Result<()> {
loop {
terminal.draw(|f| ui(f, &mut app))?;

Expand Down

0 comments on commit 4d4f5c2

Please sign in to comment.