-
-
Notifications
You must be signed in to change notification settings - Fork 159
feature: add resource detail view #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
df60c24
0e156a3
827a5f2
d650970
08eedb0
4c1279c
46bcadc
a2d723e
d1d4548
cfbc1af
d506ec5
34c6982
9311ef1
af74840
d93d336
4a342dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use std::sync::Arc; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for adding new examples, these are great! take it or leave it, but it might also be nice to have some examples that combine multiple resource types. that way, we could simulate what a real application that uses a large number of resources might look like. we could maybe stick similar code to these examples into it would be totally fine to make that change in a follow-up branch, though. |
||
use std::time::Duration; | ||
use tokio::sync::Barrier; | ||
use tokio::task; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
console_subscriber::init(); | ||
task::Builder::default() | ||
.name("main-task") | ||
.spawn(async move { | ||
let mut handles = Vec::with_capacity(30); | ||
let barrier = Arc::new(Barrier::new(30)); | ||
for i in 0..30 { | ||
let c = barrier.clone(); | ||
let task_name = format!("task-{}", i); | ||
handles.push(task::Builder::default().name(&task_name).spawn(async move { | ||
tokio::time::sleep(Duration::from_secs(i)).await; | ||
let wait_result = c.wait().await; | ||
wait_result | ||
})); | ||
} | ||
|
||
// Will not resolve until all "after wait" messages have been printed | ||
let mut num_leaders = 0; | ||
for handle in handles { | ||
let wait_result = handle.await.unwrap(); | ||
if wait_result.is_leader() { | ||
num_leaders += 1; | ||
} | ||
} | ||
|
||
tokio::time::sleep(Duration::from_secs(10)).await; | ||
// Exactly one barrier will resolve as the "leader" | ||
assert_eq!(num_leaders, 1); | ||
}) | ||
.await?; | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use std::sync::Arc; | ||
use std::time::Duration; | ||
use tokio::{sync::Mutex, task}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
console_subscriber::init(); | ||
task::Builder::default() | ||
.name("main-task") | ||
.spawn(async move { | ||
let count = Arc::new(Mutex::new(0)); | ||
for i in 0..5 { | ||
let my_count = Arc::clone(&count); | ||
let task_name = format!("increment-{}", i); | ||
tokio::task::Builder::default() | ||
.name(&task_name) | ||
.spawn(async move { | ||
for _ in 0..10 { | ||
let mut lock = my_count.lock().await; | ||
*lock += 1; | ||
tokio::time::sleep(Duration::from_secs(1)).await; | ||
} | ||
}); | ||
} | ||
|
||
while *count.lock().await < 50 {} | ||
}) | ||
.await?; | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use std::sync::Arc; | ||
use std::time::Duration; | ||
use tokio::{sync::RwLock, task}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
console_subscriber::init(); | ||
task::Builder::default() | ||
.name("main-task") | ||
.spawn(async move { | ||
let count = Arc::new(RwLock::new(0)); | ||
for i in 0..5 { | ||
let my_count = Arc::clone(&count); | ||
let task_name = format!("increment-{}", i); | ||
tokio::task::Builder::default() | ||
.name(&task_name) | ||
.spawn(async move { | ||
for _ in 0..10 { | ||
let mut lock = my_count.write().await; | ||
*lock += 1; | ||
tokio::time::sleep(Duration::from_secs(1)).await; | ||
} | ||
}); | ||
} | ||
|
||
loop { | ||
let c = count.read().await; | ||
tokio::time::sleep(Duration::from_secs(1)).await; | ||
if *c >= 50 { | ||
break; | ||
} | ||
} | ||
}) | ||
.await?; | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use std::sync::Arc; | ||
use std::time::Duration; | ||
use tokio::task; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { | ||
console_subscriber::init(); | ||
task::Builder::default() | ||
.name("main-task") | ||
.spawn(async move { | ||
let sem = Arc::new(tokio::sync::Semaphore::new(0)); | ||
let mut tasks = Vec::default(); | ||
for i in 0..5 { | ||
let acquire_sem = Arc::clone(&sem); | ||
let add_sem = Arc::clone(&sem); | ||
let acquire_task_name = format!("acquire-{}", i); | ||
let add_task_name = format!("add-{}", i); | ||
tasks.push( | ||
tokio::task::Builder::default() | ||
.name(&acquire_task_name) | ||
.spawn(async move { | ||
let _permit = acquire_sem.acquire_many(i).await.unwrap(); | ||
tokio::time::sleep(Duration::from_secs(i as u64 * 2)).await; | ||
}), | ||
); | ||
tasks.push(tokio::task::Builder::default().name(&add_task_name).spawn( | ||
async move { | ||
tokio::time::sleep(Duration::from_secs(i as u64 * 5)).await; | ||
add_sem.add_permits(i as usize); | ||
}, | ||
)); | ||
} | ||
|
||
let all_tasks = futures::future::try_join_all(tasks); | ||
all_tasks.await.unwrap(); | ||
}) | ||
.await?; | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it might be nice if this comment explained a bit more what the "parent async op" of an async op is --- my guess is that this is for situations such as a
Sleep
inside of anInterval
, or aSemaphore
op inside a channel? but, it would be nice if the comment explained that.also, if a given async op doesn't have a parent, this will not be set, right? it might be worth documenting that as well.