@@ -422,40 +422,43 @@ pub fn FileUploadWithProgress() -> impl IntoView {
422422 #[ cfg( feature = "ssr" ) ]
423423 mod progress {
424424 use async_broadcast:: { broadcast, Receiver , Sender } ;
425- use dashmap:: DashMap ;
426425 use futures:: Stream ;
427- use std:: sync:: LazyLock ;
426+ use std:: {
427+ collections:: HashMap ,
428+ sync:: { LazyLock , RwLock } ,
429+ } ;
428430
429431 struct File {
430432 total : usize ,
431433 tx : Sender < usize > ,
432434 rx : Receiver < usize > ,
433435 }
434436
435- static FILES : LazyLock < DashMap < String , File > > =
436- LazyLock :: new ( DashMap :: new) ;
437+ static FILES : LazyLock < RwLock < HashMap < String , File > > > =
438+ LazyLock :: new ( || RwLock :: new ( HashMap :: new ( ) ) ) ;
437439
438440 pub async fn add_chunk ( filename : & str , len : usize ) {
439441 println ! ( "[{filename}]\t adding {len}" ) ;
440- let mut entry =
441- FILES . entry ( filename. to_string ( ) ) . or_insert_with ( || {
442- println ! ( "[{filename}]\t inserting channel" ) ;
443- // NOTE: this channel capacity is set arbitrarily for this demo code.
444- // it allows for up to exactly 1048 chunks to be sent, which sets an upper cap
445- // on upload size (the precise details vary by client)
446- // in a real system, you will want to create some more reasonable ways of
447- // sending and sharing notifications
448- //
449- // see https://github.com/leptos-rs/leptos/issues/4397 for related discussion
450- let ( tx, rx) = broadcast ( 1048 ) ;
451- File { total : 0 , tx, rx }
452- } ) ;
453- entry. total += len;
454- let new_total = entry. total ;
455-
456- // we're about to do an async broadcast, so we don't want to hold a lock across it
457- let tx = entry. tx . clone ( ) ;
458- drop ( entry) ;
442+ let ( tx, new_total) = {
443+ let mut lock = FILES . write ( ) . unwrap ( ) ;
444+ let entry =
445+ lock. entry ( filename. to_string ( ) ) . or_insert_with ( || {
446+ println ! ( "[{filename}]\t inserting channel" ) ;
447+ // NOTE: this channel capacity is set arbitrarily for this demo code.
448+ // it allows for up to exactly 1048 chunks to be sent, which sets an upper cap
449+ // on upload size (the precise details vary by client)
450+ // in a real system, you will want to create some more reasonable ways of
451+ // sending and sharing notifications
452+ //
453+ // see https://github.com/leptos-rs/leptos/issues/4397 for related discussion
454+ let ( tx, rx) = broadcast ( 1048 ) ;
455+ File { total : 0 , tx, rx }
456+ } ) ;
457+ entry. total += len;
458+ let new_total = entry. total ;
459+
460+ ( entry. tx . clone ( ) , new_total)
461+ } ;
459462
460463 // now we send the message and don't have to worry about it
461464 tx. broadcast ( new_total)
@@ -464,12 +467,12 @@ pub fn FileUploadWithProgress() -> impl IntoView {
464467 }
465468
466469 pub fn for_file ( filename : & str ) -> impl Stream < Item = usize > {
467- let entry =
468- FILES . entry ( filename. to_string ( ) ) . or_insert_with ( || {
469- println ! ( "[{filename}]\t inserting channel" ) ;
470- let ( tx, rx) = broadcast ( 128 ) ;
471- File { total : 0 , tx, rx }
472- } ) ;
470+ let mut lock = FILES . write ( ) . unwrap ( ) ;
471+ let entry = lock . entry ( filename. to_string ( ) ) . or_insert_with ( || {
472+ println ! ( "[{filename}]\t inserting channel" ) ;
473+ let ( tx, rx) = broadcast ( 128 ) ;
474+ File { total : 0 , tx, rx }
475+ } ) ;
473476 entry. rx . clone ( )
474477 }
475478 }
0 commit comments