cancel previous async loading operations on page update

This commit is contained in:
yggverse 2024-11-09 06:53:32 +02:00
parent 35fe1f83e9
commit 675e4f328c

View File

@ -24,15 +24,17 @@ use gtk::{
RegexMatchFlags, Uri, UriFlags, UriHideFlags, RegexMatchFlags, Uri, UriFlags, UriHideFlags,
}, },
prelude::{ prelude::{
ActionExt, IOStreamExt, OutputStreamExt, SocketClientExt, StaticVariantType, ToVariant, ActionExt, CancellableExt, IOStreamExt, OutputStreamExt, SocketClientExt,
StaticVariantType, ToVariant,
}, },
Box, Box,
}; };
use sqlite::Transaction; use sqlite::Transaction;
use std::{rc::Rc, time::Duration}; use std::{cell::RefCell, rc::Rc, time::Duration};
pub struct Page { pub struct Page {
id: GString, id: GString,
cancellable: RefCell<Cancellable>,
// Actions // Actions
browser_action: Rc<BrowserAction>, browser_action: Rc<BrowserAction>,
action_page_load: SimpleAction, action_page_load: SimpleAction,
@ -91,6 +93,7 @@ impl Page {
// Init `Self` // Init `Self`
let this = Rc::new(Self { let this = Rc::new(Self {
cancellable: RefCell::new(Cancellable::new()),
id, id,
// Actions // Actions
browser_action, browser_action,
@ -183,6 +186,18 @@ impl Page {
// Reset widgets // Reset widgets
self.input.unset(); self.input.unset();
// Cancel previous async loading operations
{
let cancellable = self.cancellable.borrow();
if !cancellable.is_cancelled() {
cancellable.cancel();
}
}
// Create new cancellable pointer
self.cancellable.replace(Cancellable::new());
// Create shared variant value // Create shared variant value
let id = self.id.to_variant(); let id = self.id.to_variant();
@ -429,6 +444,7 @@ impl Page {
// use gemini::client::response:: // use gemini::client::response::
// Init shared objects (async) // Init shared objects (async)
let cancellable = self.cancellable.borrow().clone();
let update = self.browser_action.update().clone(); let update = self.browser_action.update().clone();
let action_page_load = self.action_page_load.clone(); let action_page_load = self.action_page_load.clone();
let action_page_open = self.action_page_open.clone(); let action_page_open = self.action_page_open.clone();
@ -471,21 +487,21 @@ impl Page {
client.clone().connect_to_uri_async( client.clone().connect_to_uri_async(
url.clone().as_str(), url.clone().as_str(),
1965, 1965,
None::<&Cancellable>, Some(&cancellable.clone()),
move |connect| match connect { move |connect| match connect {
Ok(connection) => { Ok(connection) => {
// Send request // Send request
connection.output_stream().write_bytes_async( connection.output_stream().write_bytes_async(
&Bytes::from(gformat!("{url}\r\n").as_bytes()), &Bytes::from(gformat!("{url}\r\n").as_bytes()),
Priority::DEFAULT, Priority::DEFAULT,
None::<&Cancellable>, Some(&cancellable.clone()),
move |request| match request { move |request| match request {
Ok(_) => { Ok(_) => {
// Read meta from input stream // Read meta from input stream
gemini::client::response::Meta::from_socket_connection_async( gemini::client::response::Meta::from_socket_connection_async(
connection.clone(), connection.clone(),
Some(Priority::DEFAULT), Some(Priority::DEFAULT),
None::<Cancellable>, Some(cancellable.clone()),
move |result| match result move |result| match result
{ {
Ok(response) => { Ok(response) => {
@ -535,7 +551,7 @@ impl Page {
gemini::client::response::data::Text::from_socket_connection_async( gemini::client::response::data::Text::from_socket_connection_async(
connection, connection,
Some(Priority::DEFAULT), Some(Priority::DEFAULT),
None::<Cancellable>, Some(cancellable.clone()),
move |result|{ move |result|{
match result { match result {
Ok(buffer) => { Ok(buffer) => {
@ -602,7 +618,7 @@ impl Page {
// this action allows to count the bytes for loading widget and validate max size for incoming data // this action allows to count the bytes for loading widget and validate max size for incoming data
gemini::gio::memory_input_stream::from_socket_connection_async( gemini::gio::memory_input_stream::from_socket_connection_async(
connection, connection,
None::<Cancellable>, Some(cancellable.clone()),
Priority::DEFAULT, Priority::DEFAULT,
0x400, // 1024 bytes per chunk, optional step for images download tracking 0x400, // 1024 bytes per chunk, optional step for images download tracking
0xA00000, // 10M bytes max to prevent memory overflow if server play with promises 0xA00000, // 10M bytes max to prevent memory overflow if server play with promises
@ -616,7 +632,7 @@ impl Page {
Ok(memory_input_stream) => { Ok(memory_input_stream) => {
Pixbuf::from_stream_async( Pixbuf::from_stream_async(
&memory_input_stream, &memory_input_stream,
None::<&Cancellable>, Some(&cancellable),
move |result| { move |result| {
match result { match result {
Ok(buffer) => { Ok(buffer) => {