@@ -3,7 +3,7 @@ use crate::cachestore::cache_item::{
33} ;
44use crate :: cachestore:: queue_item:: {
55 QueueItem , QueueItemIndexKey , QueueItemRocksIndex , QueueItemRocksTable , QueueItemStatus ,
6- QueueResultAckEvent , QueueResultAckEventResult ,
6+ QueueResultAckEvent , QueueResultAckEventResult , QueueRetrieveResponse ,
77} ;
88use crate :: cachestore:: queue_result:: {
99 QueueResultIndexKey , QueueResultRocksIndex , QueueResultRocksTable ,
@@ -266,17 +266,6 @@ impl RocksCacheStore {
266266 . await
267267 }
268268
269- fn queue_count_by_prefix_and_status (
270- db_ref : DbTableRef ,
271- prefix : & Option < String > ,
272- status : QueueItemStatus ,
273- ) -> Result < u64 , CubeError > {
274- let queue_schema = QueueItemRocksTable :: new ( db_ref. clone ( ) ) ;
275- let index_key =
276- QueueItemIndexKey :: ByPrefixAndStatus ( prefix. clone ( ) . unwrap_or ( "" . to_string ( ) ) , status) ;
277- queue_schema. count_rows_by_index ( & index_key, & QueueItemRocksIndex :: ByPrefixAndStatus )
278- }
279-
280269 fn filter_to_cancel (
281270 now : DateTime < Utc > ,
282271 items : Vec < IdRow < QueueItem > > ,
@@ -386,7 +375,7 @@ pub trait CacheStore: DIService + Send + Sync {
386375 & self ,
387376 key : String ,
388377 allow_concurrency : u32 ,
389- ) -> Result < Option < IdRow < QueueItem > > , CubeError > ;
378+ ) -> Result < QueueRetrieveResponse , CubeError > ;
390379 async fn queue_ack ( & self , key : String , result : Option < String > ) -> Result < ( ) , CubeError > ;
391380 async fn queue_result ( & self , key : String ) -> Result < Option < QueueResultResponse > , CubeError > ;
392381 async fn queue_result_blocking (
@@ -538,16 +527,17 @@ impl CacheStore for RocksCacheStore {
538527 self . store
539528 . write_operation ( move |db_ref, batch_pipe| {
540529 let queue_schema = QueueItemRocksTable :: new ( db_ref. clone ( ) ) ;
530+ let pending = queue_schema. count_rows_by_index (
531+ & QueueItemIndexKey :: ByPrefixAndStatus (
532+ item. get_prefix ( ) . clone ( ) . unwrap_or ( "" . to_string ( ) ) ,
533+ QueueItemStatus :: Pending ,
534+ ) ,
535+ & QueueItemRocksIndex :: ByPrefixAndStatus ,
536+ ) ?;
537+
541538 let index_key = QueueItemIndexKey :: ByPath ( item. get_path ( ) ) ;
542539 let id_row_opt = queue_schema
543540 . get_single_opt_row_by_index ( & index_key, & QueueItemRocksIndex :: ByPath ) ?;
544-
545- let pending = Self :: queue_count_by_prefix_and_status (
546- db_ref,
547- item. get_prefix ( ) ,
548- QueueItemStatus :: Pending ,
549- ) ?;
550-
551541 let added = if id_row_opt. is_none ( ) {
552542 queue_schema. insert ( item, batch_pipe) ?;
553543
@@ -697,44 +687,61 @@ impl CacheStore for RocksCacheStore {
697687 & self ,
698688 key : String ,
699689 allow_concurrency : u32 ,
700- ) -> Result < Option < IdRow < QueueItem > > , CubeError > {
690+ ) -> Result < QueueRetrieveResponse , CubeError > {
701691 self . store
702692 . write_operation ( move |db_ref, batch_pipe| {
703693 let queue_schema = QueueItemRocksTable :: new ( db_ref. clone ( ) ) ;
704- let index_key = QueueItemIndexKey :: ByPath ( key. clone ( ) ) ;
705- let id_row_opt = queue_schema
706- . get_single_opt_row_by_index ( & index_key , & QueueItemRocksIndex :: ByPath ) ? ;
694+ let prefix = QueueItem :: parse_path ( key. clone ( ) )
695+ . 0
696+ . unwrap_or ( "" . to_string ( ) ) ;
707697
708- if let Some ( id_row) = id_row_opt {
709- if id_row. get_row ( ) . get_status ( ) == & QueueItemStatus :: Pending {
710- let current_active = Self :: queue_count_by_prefix_and_status (
711- db_ref,
712- id_row. get_row ( ) . get_prefix ( ) ,
713- QueueItemStatus :: Active ,
714- ) ?;
715- if current_active >= ( allow_concurrency as u64 ) {
716- return Ok ( None ) ;
717- }
698+ let mut pending = queue_schema. count_rows_by_index (
699+ & QueueItemIndexKey :: ByPrefixAndStatus ( prefix. clone ( ) , QueueItemStatus :: Pending ) ,
700+ & QueueItemRocksIndex :: ByPrefixAndStatus ,
701+ ) ?;
718702
719- let mut new = id_row. get_row ( ) . clone ( ) ;
720- new. status = QueueItemStatus :: Active ;
721- // It's an important to insert heartbeat, because
722- // without that created datetime will be used for orphaned filtering
723- new. update_heartbeat ( ) ;
703+ let mut active: Vec < String > = queue_schema
704+ . get_rows_by_index (
705+ & QueueItemIndexKey :: ByPrefixAndStatus ( prefix, QueueItemStatus :: Active ) ,
706+ & QueueItemRocksIndex :: ByPrefixAndStatus ,
707+ ) ?
708+ . into_iter ( )
709+ . map ( |item| item. into_row ( ) . key )
710+ . collect ( ) ;
711+ if active. len ( ) >= ( allow_concurrency as usize ) {
712+ return Ok ( QueueRetrieveResponse :: NotFound { pending, active } ) ;
713+ }
724714
725- let res = queue_schema. update (
726- id_row. get_id ( ) ,
727- new,
728- id_row. get_row ( ) ,
729- batch_pipe,
730- ) ?;
715+ let id_row = queue_schema. get_single_opt_row_by_index (
716+ & QueueItemIndexKey :: ByPath ( key. clone ( ) ) ,
717+ & QueueItemRocksIndex :: ByPath ,
718+ ) ?;
719+ let id_row = if let Some ( id_row) = id_row {
720+ id_row
721+ } else {
722+ return Ok ( QueueRetrieveResponse :: NotFound { pending, active } ) ;
723+ } ;
731724
732- Ok ( Some ( res) )
733- } else {
734- Ok ( None )
735- }
725+ if id_row. get_row ( ) . get_status ( ) == & QueueItemStatus :: Pending {
726+ let mut new = id_row. get_row ( ) . clone ( ) ;
727+ new. status = QueueItemStatus :: Active ;
728+ // It's an important to insert heartbeat, because
729+ // without that created datetime will be used for orphaned filtering
730+ new. update_heartbeat ( ) ;
731+
732+ let res =
733+ queue_schema. update ( id_row. get_id ( ) , new, id_row. get_row ( ) , batch_pipe) ?;
734+
735+ active. push ( res. get_row ( ) . get_key ( ) . clone ( ) ) ;
736+ pending -= 1 ;
737+
738+ Ok ( QueueRetrieveResponse :: Success {
739+ item : res. into_row ( ) ,
740+ pending,
741+ active,
742+ } )
736743 } else {
737- Ok ( None )
744+ Ok ( QueueRetrieveResponse :: LockFailed { pending , active } )
738745 }
739746 } )
740747 . await
@@ -964,7 +971,7 @@ impl CacheStore for ClusterCacheStoreClient {
964971 & self ,
965972 _key : String ,
966973 _allow_concurrency : u32 ,
967- ) -> Result < Option < IdRow < QueueItem > > , CubeError > {
974+ ) -> Result < QueueRetrieveResponse , CubeError > {
968975 panic ! ( "CacheStore cannot be used on the worker node! queue_retrieve was used." )
969976 }
970977
0 commit comments