@@ -20,8 +20,8 @@ import (
2020// The scheduler may wait and retry Resume until a slot frees.
2121var ErrAllSemanticLocked = errors .New ("semantic-score: all candidates locked and override disabled" )
2222
23- // ErrNotBestWaiter means another Resume knocker has a higher admit keepScore.
24- // The scheduler retries until this sandbox becomes the best waiter (continuous knock) .
23+ // ErrNotBestWaiter means another Resume waiter has a higher admit keepScore.
24+ // The caller stays in the lobby (does not Place/Evict) until it becomes top-ranked .
2525var ErrNotBestWaiter = errors .New ("semantic-score: not highest-score Resume waiter" )
2626
2727// SemanticScore places onto the least-loaded idle Worker; when full, suspends the
@@ -76,18 +76,19 @@ func (p *SemanticScore) Place(_ context.Context, req PlaceRequest) (PlaceResult,
7676}
7777
7878func (p * SemanticScore ) Resume (ctx context.Context , req ResumeRequest ) (PlaceResult , error ) {
79+ // Rank waiters first: only the top score may sticky-place or preempt.
80+ if err := p .RequireBestWaiter (req ); err != nil {
81+ return PlaceResult {}, err
82+ }
7983 if res , ok := tryStickyResume (req , "semantic-score: sticky resume to last idle worker" ); ok {
8084 return res , nil
8185 }
82- // Among concurrent knockers, only the highest keepScore may take an idle
83- // slot or preempt (typically llm_wait). Others keep knocking.
84- if err := p .requireBestWaiter (req ); err != nil {
85- return PlaceResult {}, err
86- }
8786 return p .Place (ctx , placeFromResume (req ))
8887}
8988
90- func (p * SemanticScore ) requireBestWaiter (req ResumeRequest ) error {
89+ // RequireBestWaiter returns ErrNotBestWaiter unless req.Sandbox has the highest
90+ // admit keepScore among Waiting (continuous single-knocker ranking).
91+ func (p * SemanticScore ) RequireBestWaiter (req ResumeRequest ) error {
9192 if len (req .Waiting ) == 0 {
9293 return nil
9394 }
0 commit comments