add missing code and fix indentation and typos

This commit is contained in:
glyph 2022-09-07 17:22:56 +01:00
parent 97693bf6d9
commit aff1e5777c
4 changed files with 57 additions and 22 deletions

2
Cargo.lock generated
View File

@ -1655,7 +1655,7 @@ dependencies = [
]
[[package]]
name = "part_6_update_ui"
name = "part_6_ui_layout"
version = "0.1.0"
dependencies = [
"async-std",

View File

@ -4,7 +4,7 @@
### Introduction
In the last tutorial installment we updated the user interface of our application and added the ability to display a list of peer subscriptions. Today we'll turn our attention to staying up to date with the latest posts authored by the peers we subscribe to. In doing so, we'll add the ability to keep track of the latest sequence number for each peer we follow - as well as syncing only the latest posts for each peer.
In the last tutorial installment we updated the user interface of our application and added the ability to display a list of peer subscriptions. Today we'll turn our attention to staying up-to-date with the latest posts authored by the peers we subscribe to. In doing so, we'll add the ability to keep track of the latest sequence number for each peer we follow - as well as syncing only the latest posts for each peer.
This installment will be a short one, since much of the groundwork has already been done in previous installments.
@ -13,10 +13,10 @@ This installment will be a short one, since much of the groundwork has already b
- Update the database to store the latest sequence number
- Update the sequence number when fetching posts
- Add a task to fetch the latest posts
- Add a route handler to invoke the FetchLatestPosts task
- Add a route handler to invoke the `FetchLatestPosts` task
- Update the navigation template
### Update the Database to Store Latest Sequence Number
### Update the Database to Store the Latest Sequence Number
The main objective of this tutorial installment is to be able to request only the latest messages for each peer we subscribe to from the sbot. In order to do so, we need to know the sequence number of the most recently published message already in our key-value store. With that information, we can say to the sbot: "please give me all messages for peer X with sequence number greater than Y".
@ -30,7 +30,7 @@ We're going to add a `latest_sequence` field to the `Peer` struct in our databas
pub struct Peer {
pub public_key: String,
pub name: String,
pub latest_sequence: u64,
pub latest_sequence: u64,
}
impl Peer {
@ -38,12 +38,12 @@ impl Peer {
Peer {
public_key: public_key.to_string(),
name: "".to_string(),
// Set the value of latest_sequence to 0.
// Set the value of latest_sequence to 0.
latest_sequence: 0,
}
}
// ...
// ...
// Modify the latest_sequence field of an instance of the Peer struct,
// leaving the other values unchanged.
@ -58,7 +58,7 @@ impl Peer {
### Update the Sequence Number When Fetching Posts
Now that we have a way to store and update the latest sequence number for each peer i our database, we need to update our post-fetching function in the task loop accordingly.
Now that we have a way to store and update the latest sequence number for each peer in our database, we need to update our post-fetching function in the task loop accordingly.
`src/task_loop.rs`
@ -103,13 +103,13 @@ pub enum Task {
FetchLatestName(String),
}
/// Spawn an asynchronous loop which receives tasks over an unbounded channel
/// and invokes task functions accordingly.
// Spawn an asynchronous loop which receives tasks over an unbounded channel
// and invokes task functions accordingly.
pub async fn spawn(db: Database, rx: Receiver<Task>) {
task::spawn(async move {
while let Ok(task) = rx.recv().await {
match task {
// Fetch only the latest messages authored by the given peer,
// Fetch only the latest messages authored by the given peer,
// ie. messages with sequence numbers greater than those
// which are already stored in the database.
//
@ -121,14 +121,14 @@ pub async fn spawn(db: Database, rx: Receiver<Task>) {
fetch_posts_and_update_db(&db, peer_id, peer.latest_sequence).await;
}
}
// ...
}
}
}
// ...
}
}
}
}
```
You'll notice that the same function (`fetch_posts_and_update_db()`) is called for both the `FetchAllPosts` and `FetchLatestPosts` tasks; the difference is the value passed in for the third parameter: `after_sequence`. When fetching all posts we pass in a value of 0, while the value of `peer.latest_sequence` is passed when fetching only the latest posts. This relatively simple addition to our code has provided a very efficient means of syncing the latest posts from our local go-sbot instance to our key-value database.
You'll notice that the same function (`fetch_posts_and_update_db()`) is called by both the `FetchAllPosts` and `FetchLatestPosts` tasks; the difference is the value passed in for the third parameter: `after_sequence`. When fetching all posts we pass in a value of 0, while the value of `peer.latest_sequence` is passed when fetching only the latest posts. This relatively simple addition to our code has provided a very efficient means of syncing the latest posts from our local go-sbot instance to the key-value database.
### Add a Route Handler to Invoke the FetchLatestPosts Task
@ -140,7 +140,7 @@ Now we can begin exposing a means for the user to invoke the `FetchLatestPosts`
#[get("/posts/download_latest")]
pub async fn download_latest_posts(db: &State<Database>, tx: &State<Sender<Task>>) -> Redirect {
// Iterate through the list of peers in the key-value database.
// These are all the peers we're subscribed to via lykin.
// These are all the peers we're subscribed to via lykin.
for peer in db.get_peers() {
// Fetch the latest root posts authored by each peer we're
// subscribed to. Posts will be added to the key-value database.
@ -164,7 +164,7 @@ pub async fn download_latest_posts(db: &State<Database>, tx: &State<Sender<Task>
You'll notice in the code above that we also invoke the `FetchLatestName` task for each peer. This ensures that our application stays up-to-date with the ways our peers have chosen to name themselves.
Now we need to mount the `download_latest_posts()` route to our Rocket application:
Now we need to mount the `download_latest_posts` route to our Rocket application:
`src/main.rs`
@ -183,7 +183,7 @@ async fn rocket() -> _ {
home,
subscribe_form,
unsubscribe_form,
// Here we add the route we just wrote.
// Here we add the route we just wrote.
download_latest_posts
],
)
@ -206,10 +206,10 @@ We need to remove the `disabled` and `icon` classes from the 'Download latest po
<div class="nav">
<div class="flex-container">
<a href="/posts/download_latest" title="Download latest posts">
<img src="/icons/download.png">
<img src="/icons/download.png">
</a>
<!-- ... -->
</div>
<!-- ... -->
</div>
</div>
```

View File

@ -117,3 +117,25 @@ pub async fn unsubscribe_form(
Ok(Redirect::to(uri!(home)))
}
#[get("/posts/download_latest")]
pub async fn download_latest_posts(db: &State<Database>, tx: &State<Sender<Task>>) -> Redirect {
for peer in db.get_peers() {
// Fetch the latest root posts authored by each peer we're
// subscribed to. Posts will be added to the key-value database.
if let Err(e) = tx
.send(Task::FetchLatestPosts(peer.public_key.clone()))
.await
{
warn!("Task loop error: {}", e)
}
// Fetch the latest name for each peer we're subscribed to and update
// the database.
if let Err(e) = tx.send(Task::FetchLatestName(peer.public_key)).await {
warn!("Task loop error: {}", e)
}
}
Redirect::to(uri!(home))
}

View File

@ -50,6 +50,7 @@ async fn fetch_name_and_update_db(db: &Database, peer_id: String) {
pub enum Task {
Cancel,
FetchAllPosts(String),
FetchLatestPosts(String),
FetchLatestName(String),
}
@ -66,6 +67,18 @@ pub async fn spawn(db: Database, rx: Receiver<Task>) {
info!("Fetching all posts for peer: {}", peer_id);
fetch_posts_and_update_db(&db, peer_id, 0).await;
}
// Fetch only the latest messages authored by the given peer,
// ie. messages with sequence numbers greater than those
// which are already stored in the database.
//
// Retrieve the root posts from those messages and insert them
// into the posts tree of the database.
Task::FetchLatestPosts(peer_id) => {
if let Ok(Some(peer)) = db.get_peer(&peer_id) {
info!("Fetching latest posts for peer: {}", peer_id);
fetch_posts_and_update_db(&db, peer_id, peer.latest_sequence).await;
}
}
// Fetch the latest name for the given peer and update the
// peer entry in the peers tree of the database.
Task::FetchLatestName(peer_id) => {