Prechádzať zdrojové kódy

bin/app: reduce outbound connections while screen is off

shayan13g 5 dní pred
rodič
commit
d094f58c2b

+ 1 - 15
bin/app/src/app/mod.rs

@@ -229,7 +229,7 @@ impl App {
     pub fn stop(&self) {
     pub fn stop(&self) {
         let window_node = self.sg_root.lookup_node("/window").unwrap();
         let window_node = self.sg_root.lookup_node("/window").unwrap();
         match window_node.pimpl() {
         match window_node.pimpl() {
-            Pimpl::Window(win) => win.stop(),
+            Pimpl::Window(win) => win.stop(self.ex.clone()),
             _ => panic!("wrong pimpl"),
             _ => panic!("wrong pimpl"),
         }
         }
     }
     }
@@ -241,18 +241,4 @@ impl App {
             _ => panic!("wrong pimpl"),
             _ => panic!("wrong pimpl"),
         }
         }
     }
     }
-
-    pub fn notify_start(&self) {
-        let window = self.sg_root.lookup_node("/window").unwrap();
-        smol::block_on(async {
-            window.trigger("start", vec![]).await.unwrap();
-        });
-    }
-
-    pub fn notify_stop(&self) {
-        let window = self.sg_root.lookup_node("/window").unwrap();
-        smol::block_on(async {
-            window.trigger("stop", vec![]).await.unwrap();
-        });
-    }
 }
 }

+ 6 - 0
bin/app/src/app/node.rs

@@ -51,6 +51,12 @@ pub fn create_window(name: &str) -> SceneNode {
 
 
     node.add_signal("start", "App UI started", vec![]).unwrap();
     node.add_signal("start", "App UI started", vec![]).unwrap();
     node.add_signal("stop", "App UI stopped", vec![]).unwrap();
     node.add_signal("stop", "App UI stopped", vec![]).unwrap();
+    node.add_signal(
+        "screen_changed",
+        "Screen state changed",
+        vec![("on", "Whether the screen is on", CallArgType::Bool)],
+    )
+    .unwrap();
 
 
     node
     node
 }
 }

+ 11 - 0
bin/app/src/gfx/ev.rs

@@ -44,6 +44,7 @@ impl<T> EventChannel<T> {
 pub type GraphicsEventPublisherPtr = Arc<GraphicsEventPublisher>;
 pub type GraphicsEventPublisherPtr = Arc<GraphicsEventPublisher>;
 
 
 pub struct GraphicsEventPublisher {
 pub struct GraphicsEventPublisher {
+    screen_changed: EventChannel<bool>,
     resize: EventChannel<Dimension>,
     resize: EventChannel<Dimension>,
     key_down: EventChannel<(KeyCode, KeyMods, bool)>,
     key_down: EventChannel<(KeyCode, KeyMods, bool)>,
     key_up: EventChannel<(KeyCode, KeyMods)>,
     key_up: EventChannel<(KeyCode, KeyMods)>,
@@ -55,6 +56,7 @@ pub struct GraphicsEventPublisher {
     touch: EventChannel<(TouchPhase, u64, Point)>,
     touch: EventChannel<(TouchPhase, u64, Point)>,
 }
 }
 
 
+pub type GraphicsEventScreenSub = async_channel::Receiver<bool>;
 pub type GraphicsEventResizeSub = async_channel::Receiver<Dimension>;
 pub type GraphicsEventResizeSub = async_channel::Receiver<Dimension>;
 pub type GraphicsEventKeyDownSub = async_channel::Receiver<(KeyCode, KeyMods, bool)>;
 pub type GraphicsEventKeyDownSub = async_channel::Receiver<(KeyCode, KeyMods, bool)>;
 pub type GraphicsEventKeyUpSub = async_channel::Receiver<(KeyCode, KeyMods)>;
 pub type GraphicsEventKeyUpSub = async_channel::Receiver<(KeyCode, KeyMods)>;
@@ -68,6 +70,7 @@ pub type GraphicsEventTouchSub = async_channel::Receiver<(TouchPhase, u64, Point
 impl GraphicsEventPublisher {
 impl GraphicsEventPublisher {
     pub fn new() -> Arc<Self> {
     pub fn new() -> Arc<Self> {
         Arc::new(Self {
         Arc::new(Self {
+            screen_changed: EventChannel::new(),
             resize: EventChannel::new(),
             resize: EventChannel::new(),
             key_down: EventChannel::new(),
             key_down: EventChannel::new(),
             key_up: EventChannel::new(),
             key_up: EventChannel::new(),
@@ -80,6 +83,10 @@ impl GraphicsEventPublisher {
         })
         })
     }
     }
 
 
+    pub(super) fn notify_screen_changed(&self, screen_on: bool) {
+        self.screen_changed.notify(screen_on);
+    }
+
     pub(super) fn notify_resize(&self, screen_size: Dimension) {
     pub(super) fn notify_resize(&self, screen_size: Dimension) {
         self.resize.notify(screen_size);
         self.resize.notify(screen_size);
     }
     }
@@ -115,6 +122,10 @@ impl GraphicsEventPublisher {
         self.touch.notify(ev);
         self.touch.notify(ev);
     }
     }
 
 
+    pub fn subscribe_screen_changed(&self) -> GraphicsEventScreenSub {
+        self.screen_changed.clone_recvr()
+    }
+
     pub fn subscribe_resize(&self) -> GraphicsEventResizeSub {
     pub fn subscribe_resize(&self) -> GraphicsEventResizeSub {
         self.resize.clone_recvr()
         self.resize.clone_recvr()
     }
     }

+ 10 - 0
bin/app/src/gfx/mod.rs

@@ -953,6 +953,16 @@ impl EventHandler for Stage {
         self.screen_state.update(self.egl_ctx_is_disabled());
         self.screen_state.update(self.egl_ctx_is_disabled());
         if self.screen_state != old_screen_state {
         if self.screen_state != old_screen_state {
             d!("Switching screen state {old_screen_state:?} => {:?}", self.screen_state);
             d!("Switching screen state {old_screen_state:?} => {:?}", self.screen_state);
+
+            match self.screen_state {
+                ScreenState::SwitchOff => {
+                    self.event_pub.notify_screen_changed(false);
+                }
+                ScreenState::ReadyOn => {
+                    self.event_pub.notify_screen_changed(true);
+                }
+                _ => {}
+            }
         }
         }
 
 
         match self.screen_state {
         match self.screen_state {

+ 0 - 3
bin/app/src/main.rs

@@ -253,13 +253,10 @@ impl God {
             cv.wait().await;
             cv.wait().await;
             app.start(event_pub, epoch).await;
             app.start(event_pub, epoch).await;
         });
         });
-
-        self.app.notify_start();
     }
     }
 
 
     /// Put the app to sleep until the next restart.
     /// Put the app to sleep until the next restart.
     pub fn stop_app(&self) {
     pub fn stop_app(&self) {
-        self.app.notify_stop();
         self.fg_runtime.stop();
         self.fg_runtime.stop();
         self.app.stop();
         self.app.stop();
         info!(target: "main", "App stopped");
         info!(target: "main", "App stopped");

+ 63 - 13
bin/app/src/plugin/darkirc.rs

@@ -79,7 +79,7 @@ const DAGS_COUNT: u64 = 24;
 /// Milliseconds in one rotation period (1 hour).
 /// Milliseconds in one rotation period (1 hour).
 const HOUR_MS: u64 = 3_600_000;
 const HOUR_MS: u64 = 3_600_000;
 
 
-pub(crate) const P2P_OUTBOUND_ACTIVE: usize = 6;
+pub(crate) const P2P_OUTBOUND_ACTIVE: usize = 3;
 const P2P_OUTBOUND_SLEEP: usize = 1;
 const P2P_OUTBOUND_SLEEP: usize = 1;
 
 
 /// Update `outbound_peers` property useful for diagnostics
 /// Update `outbound_peers` property useful for diagnostics
@@ -335,6 +335,8 @@ impl DarkIrc {
             ex: ex.clone(),
             ex: ex.clone(),
         });
         });
 
 
+        self_.p2p.settings().write().await.outbound_connections = P2P_OUTBOUND_ACTIVE;
+
         ensure_joined_channels_seeded();
         ensure_joined_channels_seeded();
         self_.load_channels_from_db().await;
         self_.load_channels_from_db().await;
         self_.load_contacts_from_db().await;
         self_.load_contacts_from_db().await;
@@ -926,7 +928,32 @@ impl DarkIrc {
         i!("P2P reconnection completed");
         i!("P2P reconnection completed");
     }
     }
 
 
-    async fn start(self: Arc<Self>, sg_root: SceneNodePtr, ex: ExecutorPtr) {
+    async fn set_outbound_connections(&self, count: usize) {
+        let p2p_settings = self.p2p.settings();
+
+        if p2p_settings.read().await.outbound_connections == count {
+            return;
+        }
+
+        p2p_settings.write().await.outbound_connections = count;
+        self.p2p.clone().reload().await;
+
+        let setting = self.settings.get_setting("net.outbound_connections").unwrap();
+        setting
+            .set_property_u32(
+                &mut PropertyAtomicGuard::none(),
+                Role::Internal,
+                "value",
+                count as u32,
+            )
+            .unwrap();
+    }
+
+    async fn start(
+        self: Arc<Self>,
+        sg_root: SceneNodePtr,
+        ex: ExecutorPtr,
+    ) {
         i!("Registering EventGraph P2P protocol");
         i!("Registering EventGraph P2P protocol");
         let event_graph_ = Arc::clone(&self.event_graph);
         let event_graph_ = Arc::clone(&self.event_graph);
         let registry = self.p2p.protocol_registry();
         let registry = self.p2p.protocol_registry();
@@ -982,28 +1009,50 @@ impl DarkIrc {
         let channel_sub = self.p2p.hosts().subscribe_channel().await;
         let channel_sub = self.p2p.hosts().subscribe_channel().await;
         let dag_task = ex.spawn(self.clone().dag_sync(channel_sub));
         let dag_task = ex.spawn(self.clone().dag_sync(channel_sub));
 
 
-        // Subscribe to window start/stop signals for dynamic outbound connections
         let window_node = sg_root.lookup_node("/window").unwrap();
         let window_node = sg_root.lookup_node("/window").unwrap();
 
 
-        let (start_slot, start_recv) = Slot::new("app_start");
+        let (start_slot, start_recv) = Slot::new("darkirc_start");
         window_node.register("start", start_slot).unwrap();
         window_node.register("start", start_slot).unwrap();
-        let p2p = self.p2p.clone();
+
+        let me2 = Arc::downgrade(&self);
         let start_task = ex.spawn(async move {
         let start_task = ex.spawn(async move {
             while let Ok(_) = start_recv.recv().await {
             while let Ok(_) = start_recv.recv().await {
-                i!("App started: set outbound connections to {P2P_OUTBOUND_ACTIVE}");
-                p2p.settings().write().await.outbound_connections = P2P_OUTBOUND_ACTIVE;
-                p2p.clone().reload().await;
+                let Some(self_) = me2.upgrade() else { break };
+
+                self_.set_outbound_connections(P2P_OUTBOUND_ACTIVE).await;
             }
             }
         });
         });
 
 
-        let (stop_slot, stop_recv) = Slot::new("app_stop");
+        let (stop_slot, stop_recv) = Slot::new("darkirc_stop");
         window_node.register("stop", stop_slot).unwrap();
         window_node.register("stop", stop_slot).unwrap();
-        let p2p = self.p2p.clone();
+
+        let me2 = Arc::downgrade(&self);
         let stop_task = ex.spawn(async move {
         let stop_task = ex.spawn(async move {
             while let Ok(_) = stop_recv.recv().await {
             while let Ok(_) = stop_recv.recv().await {
-                i!("App stopped: set outbound connections to {P2P_OUTBOUND_SLEEP}");
-                p2p.settings().write().await.outbound_connections = P2P_OUTBOUND_SLEEP;
-                p2p.clone().reload().await;
+                let Some(self_) = me2.upgrade() else { break };
+
+                self_.set_outbound_connections(P2P_OUTBOUND_SLEEP).await;
+            }
+        });
+
+        let (screen_changed_slot, screen_changed_recv) = Slot::new("darkirc_screen_changed");
+        window_node.register("screen_changed", screen_changed_slot).unwrap();
+
+        let me2 = Arc::downgrade(&self);
+        let screen_changed_task = ex.spawn(async move {
+            while let Ok(data) = screen_changed_recv.recv().await {
+                let Some(self_) = me2.upgrade() else { break };
+
+                let mut cursor = Cursor::new(&data);
+                let Ok(screen_on) = bool::decode(&mut cursor) else {
+                    continue
+                };
+
+                if screen_on {
+                    self_.set_outbound_connections(P2P_OUTBOUND_ACTIVE).await;
+                } else {
+                    self_.set_outbound_connections(P2P_OUTBOUND_SLEEP).await;
+                }
             }
             }
         });
         });
 
 
@@ -1015,6 +1064,7 @@ impl DarkIrc {
             dag_task,
             dag_task,
             start_task,
             start_task,
             stop_task,
             stop_task,
+            screen_changed_task,
         ];
         ];
 
 
         if DNET_ENABLED {
         if DNET_ENABLED {

+ 34 - 1
bin/app/src/ui/win/mod.rs

@@ -145,6 +145,24 @@ impl Window {
             }
             }
         });
         });
 
 
+        let screen_sub = event_pub.subscribe_screen_changed();
+        let me2 = me.clone();
+        let screen_task = ex.spawn(async move {
+            while let Ok(screen_on) = screen_sub.recv().await {
+                let Some(self_) = me2.upgrade() else {
+                    break
+                };
+
+                self_
+                    .node
+                    .upgrade()
+                    .unwrap()
+                    .trigger("screen_changed", darkfi_serial::serialize(&screen_on))
+                    .await
+                    .unwrap();
+            }
+        });
+
         // The serialized draw pass. Single consumer: one pass runs at a
         // The serialized draw pass. Single consumer: one pass runs at a
         // time. Triggers arriving during (or pending at the end of) a pass
         // time. Triggers arriving during (or pending at the end of) a pass
         // are coalesced by the bounded(1) queue into one trailing pass.
         // are coalesced by the bounded(1) queue into one trailing pass.
@@ -240,6 +258,7 @@ impl Window {
 
 
         let mut tasks = vec![
         let mut tasks = vec![
             resize_task,
             resize_task,
+            screen_task,
             redraw_task,
             redraw_task,
             char_task,
             char_task,
             key_down_task,
             key_down_task,
@@ -255,18 +274,32 @@ impl Window {
         tasks.push(insets_task);
         tasks.push(insets_task);
         *self.tasks.lock() = tasks;
         *self.tasks.lock() = tasks;
 
 
+        self.node.upgrade().unwrap().trigger("start", vec![]).await.unwrap();
+
         for child in self.get_children() {
         for child in self.get_children() {
             let obj = get_ui_object_ptr(&child);
             let obj = get_ui_object_ptr(&child);
             obj.start(ex.clone()).await;
             obj.start(ex.clone()).await;
         }
         }
     }
     }
 
 
-    pub fn stop(&self) {
+    pub fn stop(&self, ex: ExecutorPtr) {
+        let node = self.node.clone();
+        let stop_task = ex.spawn(async move {
+            node.upgrade()
+                .unwrap()
+                .trigger("stop", vec![])
+                .await
+                .unwrap();
+        });
+
         self.tasks.lock().clear();
         self.tasks.lock().clear();
+
         for child in self.get_children() {
         for child in self.get_children() {
             let obj = get_ui_object3(&child);
             let obj = get_ui_object3(&child);
             obj.stop();
             obj.stop();
         }
         }
+
+        smol::block_on(stop_task);
     }
     }
 
 
     async fn process_char(me: &Weak<Self>, ev_sub: &GraphicsEventCharSub) -> bool {
     async fn process_char(me: &Weak<Self>, ev_sub: &GraphicsEventCharSub) -> bool {

+ 27 - 3
src/net/session/outbound_session.rs

@@ -156,11 +156,20 @@ impl OutboundSession {
     async fn add_slots(self: Arc<Self>, slots: &mut Vec<Arc<Slot>>, target: usize) {
     async fn add_slots(self: Arc<Self>, slots: &mut Vec<Arc<Slot>>, target: usize) {
         let slots_len = slots.len();
         let slots_len = slots.len();
         let self_ = Arc::downgrade(&self);
         let self_ = Arc::downgrade(&self);
-        for i in slots_len..target {
-            let slot = Slot::new(self_.clone(), i as u32);
+        for slot_id in 0..target as u32 {
+            if slots.iter().any(|slot| slot.slot == slot_id) {
+                continue
+            }
+
+            let slot = Slot::new(self_.clone(), slot_id);
             slot.clone().start().await;
             slot.clone().start().await;
             slots.push(slot);
             slots.push(slot);
+
+            if slots.len() == target {
+                break
+            }
         }
         }
+
         verbose!(target: "net::outbound_session",
         verbose!(target: "net::outbound_session",
             "[P2P] Increased outbound slots from {slots_len} to {target}");
             "[P2P] Increased outbound slots from {slots_len} to {target}");
     }
     }
@@ -256,6 +265,21 @@ impl Slot {
 
 
     async fn stop(self: Arc<Self>) {
     async fn stop(self: Arc<Self>) {
         self.connector.stop();
         self.connector.stop();
+
+        let channel_id = self.channel_id.load(Ordering::Relaxed);
+        if channel_id != 0 {
+            if let Some(channel) = self.p2p().get_channel(channel_id) {
+                channel.stop().await;
+            }
+
+            dnetev!(self, OutboundSlotDisconnected, {
+                slot: self.slot,
+                err: "Outbound slot stopped".to_string(),
+            });
+
+            self.channel_id.store(0, Ordering::Relaxed);
+        }
+
         self.process.stop().await;
         self.process.stop().await;
     }
     }
 
 
@@ -595,7 +619,7 @@ impl PeerDiscoveryBase for PeerDiscovery {
     /// attempts, this will loop through all connected P2P peers and send
     /// attempts, this will loop through all connected P2P peers and send
     /// out a `GetAddrs` message to request more peers. Other parts of the
     /// out a `GetAddrs` message to request more peers. Other parts of the
     /// P2P stack will then handle the incoming addresses and place them in
     /// P2P stack will then handle the incoming addresses and place them in
-    /// the hosts list.  
+    /// the hosts list.
     ///
     ///
     /// On the third attempt, and if we still haven't made any connections,
     /// On the third attempt, and if we still haven't made any connections,
     /// this function will then call `p2p.seed()` which triggers a
     /// this function will then call `p2p.seed()` which triggers a