@@ -102,7 +102,7 @@ cfg_if::cfg_if! {
102
102
103
103
use anyhow:: { Result , anyhow, Context } ;
104
104
use async_channel:: { Sender , Receiver , bounded} ;
105
- use async_lock :: { RwLock , RwLockUpgradableReadGuard } ;
105
+ use parking_lot :: RwLock ;
106
106
use futures_util:: { stream:: BoxStream , StreamExt } ;
107
107
use serde:: { de:: DeserializeOwned } ;
108
108
use tracing:: { warn, debug, trace} ;
@@ -133,7 +133,7 @@ cfg_if::cfg_if! {
133
133
where
134
134
S : K8ExtendedSpec ,
135
135
{
136
- let store = self . get_store:: <S >( ) . await ?;
136
+ let store = self . get_store:: <S >( ) ?;
137
137
store. retrieve_items( ) . await
138
138
}
139
139
@@ -142,7 +142,7 @@ cfg_if::cfg_if! {
142
142
S : K8ExtendedSpec ,
143
143
{
144
144
trace!( ?metadata, "delete item" ) ;
145
- let store = self . get_store:: <S >( ) . await ?;
145
+ let store = self . get_store:: <S >( ) ?;
146
146
if let Some ( item) = store. try_retrieve_item:: <S >( & metadata) . await ? {
147
147
if let Some ( owner) = item. ctx( ) . item( ) . owner( ) {
148
148
self . unlink_parent:: <S >( owner, item. ctx( ) . item( ) ) . await ?;
@@ -166,7 +166,7 @@ cfg_if::cfg_if! {
166
166
<S as Spec >:: Owner : K8ExtendedSpec ,
167
167
{
168
168
trace!( ?value, "apply" ) ;
169
- let store = self . get_store:: <S >( ) . await ?;
169
+ let store = self . get_store:: <S >( ) ?;
170
170
value. ctx_mut( ) . item_mut( ) . id = value. key( ) . to_string( ) ;
171
171
if let Some ( owner) = value. ctx( ) . item( ) . owner( ) {
172
172
self . link_parent:: <S >( owner, value. ctx( ) . item( ) ) . await ?;
@@ -181,7 +181,7 @@ cfg_if::cfg_if! {
181
181
use std:: str :: FromStr ;
182
182
183
183
trace!( ?metadata, ?spec, "update spec" ) ;
184
- let store = self . get_store:: <S >( ) . await ?;
184
+ let store = self . get_store:: <S >( ) ?;
185
185
let item = match store. try_retrieve_item:: <S >( & metadata) . await ? {
186
186
Some ( mut item) => {
187
187
item. ctx_mut( ) . set_item( metadata) ;
@@ -214,7 +214,7 @@ cfg_if::cfg_if! {
214
214
id: key. to_string( ) ,
215
215
..Default :: default ( )
216
216
} ;
217
- let store = self . get_store:: <S >( ) . await ?;
217
+ let store = self . get_store:: <S >( ) ?;
218
218
let item = match store. try_retrieve_item:: <S >( & metadata) . await ? {
219
219
Some ( mut item) => {
220
220
item. set_spec( spec) ;
@@ -235,7 +235,7 @@ cfg_if::cfg_if! {
235
235
S : K8ExtendedSpec ,
236
236
{
237
237
trace!( ?metadata, ?status, "update status" ) ;
238
- let store = self . get_store:: <S >( ) . await ?;
238
+ let store = self . get_store:: <S >( ) ?;
239
239
let mut item = store. retrieve_item:: <S >( & metadata) . await ?;
240
240
item. ctx_mut( ) . set_item( metadata. clone( ) ) ;
241
241
item. set_status( status) ;
@@ -252,12 +252,11 @@ cfg_if::cfg_if! {
252
252
S : K8ExtendedSpec ,
253
253
{
254
254
trace!( label = S :: LABEL , ?resource_version, "watch stream" ) ;
255
- futures_util:: stream:: once( self . get_store:: <S >( ) )
256
- . flat_map( move |store| match store {
257
- Ok ( store) => store. watch_stream_since( resource_version. as_ref( ) ) ,
258
- Err ( err) => futures_util:: stream:: once( async { Result :: <_>:: Err ( err) } ) . boxed( ) ,
259
- } )
260
- . boxed( )
255
+ let store = self . get_store:: <S >( ) ;
256
+ match store {
257
+ Ok ( store) => store. watch_stream_since( resource_version. as_ref( ) ) ,
258
+ Err ( err) => futures_util:: stream:: once( async { Result :: <_>:: Err ( err) } ) . boxed( ) ,
259
+ }
261
260
}
262
261
263
262
async fn patch_status<S >(
@@ -270,7 +269,7 @@ cfg_if::cfg_if! {
270
269
S : K8ExtendedSpec ,
271
270
{
272
271
trace!( ?metadata, ?status, "patch status" ) ;
273
- let store = self . get_store:: <S >( ) . await ?;
272
+ let store = self . get_store:: <S >( ) ?;
274
273
let mut item = store. retrieve_item:: <S >( & metadata) . await ?;
275
274
item. ctx_mut( ) . set_item( metadata. clone( ) ) ;
276
275
item. set_status( status) ;
@@ -309,15 +308,17 @@ cfg_if::cfg_if! {
309
308
Self { path, stores }
310
309
}
311
310
312
- async fn get_store<S : Spec + DeserializeOwned >( & self ) -> Result <Arc <SpecStore >> {
311
+ fn get_store<S : Spec + DeserializeOwned >( & self ) -> Result <Arc <SpecStore >> {
313
312
let key = S :: LABEL ;
314
- let read = self . stores. upgradable_read ( ) . await ;
313
+ let read = self . stores. read ( ) ;
315
314
Ok ( match read. get( key) {
316
315
Some ( store) => store. clone( ) ,
317
316
None => {
318
- let mut write = RwLockUpgradableReadGuard :: upgrade( read) . await ;
319
- let store = Arc :: new( SpecStore :: load:: <S , _>( self . path. join( key) ) . await ?) ;
317
+ drop( read) ;
318
+ let mut write = self . stores. write( ) ;
319
+ let store = Arc :: new( SpecStore :: load:: <S , _>( self . path. join( key) ) ?) ;
320
320
write. insert( key, store. clone( ) ) ;
321
+ drop( write) ;
321
322
store
322
323
}
323
324
} )
@@ -342,7 +343,7 @@ cfg_if::cfg_if! {
342
343
child: & LocalMetadataItem ,
343
344
) -> Result <( ) > {
344
345
trace!( ?parent, ?child, "link parent" ) ;
345
- let parent_store = self . get_store:: <S :: Owner >( ) . await ?;
346
+ let parent_store = self . get_store:: <S :: Owner >( ) ?;
346
347
parent_store
347
348
. mut_in_place:: <S :: Owner , _>( parent. uid( ) , |parent_obj| {
348
349
parent_obj
@@ -360,7 +361,7 @@ cfg_if::cfg_if! {
360
361
child: & LocalMetadataItem ,
361
362
) -> Result <( ) > {
362
363
trace!( ?parent, ?child, "link parent" ) ;
363
- let parent_store = self . get_store:: <S :: Owner >( ) . await ?;
364
+ let parent_store = self . get_store:: <S :: Owner >( ) ?;
364
365
parent_store
365
366
. mut_in_place:: <S :: Owner , _>( parent. uid( ) , |parent_obj| {
366
367
parent_obj
@@ -375,15 +376,14 @@ cfg_if::cfg_if! {
375
376
async fn get_store_by_key( & self , key: & str ) -> Result <Arc <SpecStore >> {
376
377
self . stores
377
378
. read( )
378
- . await
379
379
. get( key)
380
380
. cloned( )
381
381
. ok_or_else( || anyhow!( "store not found for key {key}" ) )
382
382
}
383
383
}
384
384
385
385
impl SpecStore {
386
- async fn load<S : Spec , P : AsRef <Path >>( path: P ) -> Result <Self > {
386
+ fn load<S : Spec , P : AsRef <Path >>( path: P ) -> Result <Self > {
387
387
std:: fs:: create_dir_all( & path) ?;
388
388
let version = Default :: default ( ) ;
389
389
let mut data: HashMap <String , SpecPointer > = Default :: default ( ) ;
@@ -423,7 +423,7 @@ cfg_if::cfg_if! {
423
423
. version
424
424
. load( std:: sync:: atomic:: Ordering :: SeqCst )
425
425
. to_string( ) ;
426
- let read = self . data. read( ) . await ;
426
+ let read = self . data. read( ) ;
427
427
let items: Vec <LocalStoreObject <S >> = read
428
428
. values( )
429
429
. map( SpecPointer :: downcast)
@@ -439,7 +439,7 @@ cfg_if::cfg_if! {
439
439
where
440
440
S : Spec ,
441
441
{
442
- let read = self . data. read( ) . await ;
442
+ let read = self . data. read( ) ;
443
443
read. get( metadata. uid( ) )
444
444
. map( SpecPointer :: downcast)
445
445
. transpose( )
@@ -455,10 +455,18 @@ cfg_if::cfg_if! {
455
455
}
456
456
457
457
async fn delete_item( & self , metadata: & LocalMetadataItem ) {
458
- let mut write = self . data. write( ) . await ;
459
- if let Some ( removed) = write. remove( metadata. uid( ) ) {
460
- removed. delete( ) ;
461
- drop( write) ;
458
+ let removed = {
459
+ let mut write = self . data. write( ) ;
460
+ if let Some ( removed) = write. remove( metadata. uid( ) ) {
461
+ removed. delete( ) ;
462
+ drop( write) ;
463
+ Some ( removed)
464
+ } else {
465
+ None
466
+ }
467
+ } ;
468
+
469
+ if let Some ( removed) = removed {
462
470
self . send_update( SpecUpdate :: Delete ( removed) ) . await ;
463
471
}
464
472
}
@@ -468,20 +476,24 @@ cfg_if::cfg_if! {
468
476
S : Spec + Serialize ,
469
477
{
470
478
let id = value. ctx( ) . item( ) . uid( ) . to_owned( ) ;
471
- let mut write = self . data. write( ) . await ;
472
- if let Some ( prev) = write. get( & id) {
473
- let prev_meta = prev. downcast_ref:: <S >( ) ?. ctx( ) . item( ) ;
474
- let prev_rev = prev_meta. revision;
475
- if prev_meta. is_newer( value. ctx( ) . item( ) ) {
476
- let new_rev = value. ctx( ) . item( ) . revision;
477
- anyhow:: bail!( "attempt to update by stale value: current version: {prev_rev}, proposed: {new_rev}" ) ;
478
- }
479
- value. ctx_mut( ) . item_mut( ) . revision = prev_rev + 1 ;
479
+ let pointer =
480
+ {
481
+ let mut write = self . data. write( ) ;
482
+ if let Some ( prev) = write. get( & id) {
483
+ let prev_meta = prev. downcast_ref:: <S >( ) ?. ctx( ) . item( ) ;
484
+ let prev_rev = prev_meta. revision;
485
+ if prev_meta. is_newer( value. ctx( ) . item( ) ) {
486
+ let new_rev = value. ctx( ) . item( ) . revision;
487
+ anyhow:: bail!( "attempt to update by stale value: current version: {prev_rev}, proposed: {new_rev}" ) ;
488
+ }
489
+ value. ctx_mut( ) . item_mut( ) . revision = prev_rev + 1 ;
490
+ } ;
491
+ let pointer = SpecPointer :: new( self . spec_file_name( & id) , value) ;
492
+ write. insert( id, pointer. clone( ) ) ;
493
+ pointer. flush:: <S >( ) ?;
494
+ drop( write) ;
495
+ pointer
480
496
} ;
481
- let pointer = SpecPointer :: new( self . spec_file_name( & id) , value) ;
482
- write. insert( id, pointer. clone( ) ) ;
483
- pointer. flush:: <S >( ) ?;
484
- drop( write) ;
485
497
self . send_update( SpecUpdate :: Mod ( pointer) ) . await ;
486
498
Ok ( ( ) )
487
499
}
@@ -522,7 +534,7 @@ cfg_if::cfg_if! {
522
534
where
523
535
F : Fn ( & mut LocalStoreObject <S >) ,
524
536
{
525
- if let Some ( spec) = self . data. write( ) . await . get_mut( key) {
537
+ if let Some ( spec) = self . data. write( ) . get_mut( key) {
526
538
let mut obj = spec. downcast:: <S >( ) ?;
527
539
func( & mut obj) ;
528
540
spec. set( obj) ;
@@ -585,7 +597,9 @@ cfg_if::cfg_if! {
585
597
586
598
fn flush<S : Spec >( & self ) -> Result <( ) > {
587
599
let storage: VersionedSpecStorage <S > = self . try_into( ) ?;
588
- serde_yaml:: to_writer( std:: fs:: File :: create( & self . path) ?, & storage) ?;
600
+ let file = std:: fs:: File :: create( & self . path) ?;
601
+ serde_yaml:: to_writer( & file, & storage) ?;
602
+ file. sync_all( ) ?;
589
603
Ok ( ( ) )
590
604
}
591
605
0 commit comments