11use axum:: { routing:: get, Router } ;
2- use futures_channel:: mpsc:: { unbounded, UnboundedSender } ;
3- use futures_util:: stream:: SelectNextSome ;
2+ use futures_channel:: mpsc:: unbounded;
43use futures_util:: { SinkExt , StreamExt } ;
5- use maud:: { html, Markup } ;
4+ use maud:: html;
65use messages:: DisplayMessage ;
7- use std:: collections:: VecDeque ;
86use std:: net:: SocketAddr ;
97use std:: {
108 collections:: HashMap ,
@@ -21,26 +19,11 @@ use tokio_tungstenite::{
2119 tungstenite:: { Error , Message , Result } ,
2220} ;
2321
24- type Tx = UnboundedSender < Message > ;
25- pub type ConnectionMap = Arc < Mutex < HashMap < SocketAddr , Tx > > > ;
26- type EventQueues = Arc < Mutex < Queues > > ;
22+ mod routes ;
23+ mod types ;
24+ use routes :: { admin , index } ;
2725
28- static EVENT_QUEUE_ACTIVE : std:: sync:: atomic:: AtomicBool = std:: sync:: atomic:: AtomicBool :: new ( true ) ;
29- static TTS_QUEUE_ACTIVE : std:: sync:: atomic:: AtomicBool = std:: sync:: atomic:: AtomicBool :: new ( false ) ;
30-
31- pub struct Queues {
32- pub events : VecDeque < DisplayMessage > ,
33- pub tts : VecDeque < DisplayMessage > ,
34- }
35-
36- impl Queues {
37- pub fn new ( ) -> Queues {
38- Queues {
39- events : VecDeque :: new ( ) ,
40- tts : VecDeque :: new ( ) ,
41- }
42- }
43- }
26+ use crate :: types:: { ConnectionMap , EventQueues , Queues } ;
4427
4528pub struct FrontendApi {
4629 ws_address : String ,
@@ -82,19 +65,26 @@ impl FrontendApi {
8265 } ) ;
8366
8467 // Process the Queues on a new thread
85-
8668 let queue_connection_state = connection_state. clone ( ) ;
69+ let event_queue = message_queue_arc. clone ( ) ;
8770 tokio:: spawn ( async move {
8871 loop {
72+ let active = types:: EVENT_QUEUE_ACTIVE . load ( std:: sync:: atomic:: Ordering :: SeqCst ) ;
73+ if !active {
74+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( 500 ) ) . await ;
75+ continue ;
76+ }
77+
8978 let message = {
90- let mut queues = message_queue_arc . lock ( ) . unwrap ( ) ;
91- queues. events . pop_front ( )
79+ let mut queues = event_queue . lock ( ) . unwrap ( ) ;
80+ queues. unpublished_events . pop_front ( )
9281 } ;
9382
9483 let Some ( message) = message else {
9584 tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( 500 ) ) . await ;
9685 continue ;
9786 } ;
87+
9888 //Make html message to send to frontend
9989 //<div id="alerts" hx-swap-oob="true">
10090 let html_message = html ! {
@@ -103,6 +93,10 @@ impl FrontendApi {
10393 img src=( message. image_url) { }
10494 }
10595 } ;
96+
97+ let mut bad_websockets = vec ! [ ] ;
98+
99+ //Send message to all connected websockets
106100 {
107101 let mut websocket_state = queue_connection_state. lock ( ) . unwrap ( ) ;
108102 for ( & addr, tx) in websocket_state. iter_mut ( ) {
@@ -111,6 +105,7 @@ impl FrontendApi {
111105 . is_err ( )
112106 {
113107 println ! ( "closing websocket message to: {} ==========" , addr) ;
108+ bad_websockets. push ( addr) ;
114109 }
115110 }
116111 }
@@ -130,6 +125,7 @@ impl FrontendApi {
130125 . is_err ( )
131126 {
132127 println ! ( "closing websocket message to: {} ==========" , addr) ;
128+ bad_websockets. push ( addr) ;
133129 }
134130 }
135131 }
@@ -140,6 +136,7 @@ impl FrontendApi {
140136 } ) ;
141137
142138 let https_address = self . http_address . clone ( ) ;
139+ let event_queues = message_queue_arc. clone ( ) ;
143140 tokio:: spawn ( async move {
144141 let listener = TcpListener :: bind ( & https_address)
145142 . await
@@ -148,9 +145,16 @@ impl FrontendApi {
148145 let app = Router :: new ( )
149146 . route ( "/" , get ( index) )
150147 . route ( "/admin" , get ( admin) )
148+ . route ( "/events/latest" , get ( routes:: get_latest_unpublished_events) )
149+ . route ( "/tts" , get ( routes:: get_all_events_in_queue) )
150+ . route ( "/events" , get ( routes:: get_all_events_in_queue) )
151+ . route ( "/events/latest/all" , get ( routes:: get_latest_events) )
152+ . route ( "/events/pause" , get ( routes:: pause_events) )
153+ . route ( "/events/start" , get ( routes:: resume_events) )
151154 //TODO: understand where to put our assets
152155 // Remember that these need served by nginx in production
153- . nest_service ( "/assets" , ServeDir :: new ( "assets" ) ) ;
156+ . nest_service ( "/assets" , ServeDir :: new ( "assets" ) )
157+ . with_state ( event_queues. clone ( ) ) ;
154158
155159 // run it
156160 axum:: serve ( listener, app) . await . unwrap ( ) ;
@@ -174,40 +178,22 @@ impl FrontendApi {
174178 }
175179}
176180
177- #[ derive( askama:: Template ) ]
178- #[ template( path = "index.html" ) ]
179- struct IndexTemplate { }
180-
181- #[ derive( askama:: Template ) ]
182- #[ template( path = "admin.html" ) ]
183- struct AdminTemplate { }
184-
185- async fn index ( ) -> IndexTemplate {
186- IndexTemplate { }
187- }
188-
189- async fn admin ( ) -> AdminTemplate {
190- AdminTemplate { }
191- }
192-
193181async fn handle_message (
194182 connection_state : ConnectionMap ,
195183 event_queues : EventQueues ,
196184 message : Option < DisplayMessage > ,
197185) {
198186 match message {
199187 Some ( message) => {
200- let mut state2 = connection_state. lock ( ) . unwrap ( ) ;
201- for ( & addr, tx) in state2. iter_mut ( ) {
202- println ! ( "Sending message to: {}" , addr) ;
188+ let mut queues = event_queues. lock ( ) . unwrap ( ) ;
203189
204- //Enqueue message
205- {
206- let mut queues = event_queues. lock ( ) . unwrap ( ) ;
207- //TODO: need to handle different types of messages
190+ //TODO: Store different types of messages in different queues
191+ queues. unpublished_events . push_back ( message. clone ( ) ) ;
208192
209- queues. events . push_back ( message. clone ( ) ) ;
210- }
193+ //add to latest events, remove oldest if over 10
194+ queues. latest_events . push_back ( message. clone ( ) ) ;
195+ if queues. latest_events . len ( ) > 10 {
196+ queues. latest_events . pop_front ( ) ;
211197 }
212198 }
213199 None => panic ! ( "Error receiving message" ) ,
@@ -247,6 +233,7 @@ async fn handle_connection(
247233 println!( "Received a message from {}: {}" , peer, msg. to_text( ) ?) ;
248234 ws_sender. send( msg) . await ?;
249235 } else if msg. is_close( ) {
236+ println!( "Issue with connection: {}" , peer) ;
250237 break ;
251238 }
252239 }
@@ -258,7 +245,11 @@ async fn handle_connection(
258245 msg = rx. next( ) => {
259246 let msg = msg. unwrap( ) ;
260247 println!( "Sending message to {}: {}" , peer, msg. to_text( ) ?) ;
261- ws_sender. send( msg) . await ?;
248+ let res = ws_sender. send( msg) . await ;
249+ if res. is_err( ) {
250+ println!( "Error sending message to {}" , peer) ;
251+ break ;
252+ }
262253 }
263254 }
264255 }
0 commit comments