@@ -440,42 +440,45 @@ func (s *Server) Inform(ctx context.Context, req *pb.TabletRequest) (*pb.TabletR
440440 var proposal pb.ZeroProposal
441441 proposal .Tablets = make ([]* pb.Tablet , 0 )
442442
443- // Acquire read lock for label-related lookups
444- s .RLock ()
445443 for _ , t := range unknownTablets {
446444 glog .Infof ("Zero.Inform: routing tablet %s (label=%q, groupId=%d)" , t .Predicate , t .Label , t .GroupId )
447- switch {
448- case x .IsReservedPredicate (t .Predicate ):
449- // Force all the reserved predicates to be allocated to group 1.
450- // This is to make it easier to stream ACL updates to all alpha servers
451- // since they only need to open one pipeline to receive updates for all
452- // ACL predicates.
453- // This will also make it easier to restore the reserved predicates after
454- // a DropAll operation.
455- t .GroupId = 1
456- case t .Label != "" :
457- {
445+ // Use closure to ensure lock is always released via defer, even on error paths.
446+ // This pattern prevents lock leaks if new error conditions are added later.
447+ if err := func () error {
448+ s .RLock ()
449+ defer s .RUnlock ()
450+ switch {
451+ case x .IsReservedPredicate (t .Predicate ):
452+ // Force all the reserved predicates to be allocated to group 1.
453+ // This is to make it easier to stream ACL updates to all alpha servers
454+ // since they only need to open one pipeline to receive updates for all
455+ // ACL predicates.
456+ // This will also make it easier to restore the reserved predicates after
457+ // a DropAll operation.
458+ t .GroupId = 1
459+ case t .Label != "" :
458460 // Labeled predicate: route to matching labeled group
459461 gid , err := s .labelGroupId (t .Label )
460462 if err != nil {
461- s .RUnlock ()
462- return nil , err
463+ return err
463464 }
464465 glog .Infof ("Zero.Inform: labeled predicate %s (label=%q) routed to group %d" , t .Predicate , t .Label , gid )
465466 t .GroupId = gid
467+ case s .isLabeledGroupId (t .GroupId ):
468+ // make sure unlabeled predicates don't go an labeled group
469+ gid , err := s .firstUnlabeledGroupId ()
470+ if err != nil {
471+ return err
472+ }
473+ t .GroupId = gid
466474 }
467- case s .isLabeledGroupId (t .GroupId ):
468- // make sure unlabeled predicates don't go an labeled group
469- gid , err := s .firstUnlabeledGroupId ()
470- if err != nil {
471- s .RUnlock ()
472- return nil , err
473- }
474- t .GroupId = gid
475+ return nil
476+ }(); err != nil {
477+ return nil , err
475478 }
476479 proposal .Tablets = append (proposal .Tablets , t )
477480 }
478- s . RUnlock ()
481+
479482 if err := s .Node .proposeAndWait (ctx , & proposal ); err != nil && err != errTabletAlreadyServed {
480483 span .AddEvent (fmt .Sprintf ("Error proposing tablet: %+v. Error: %v" , & proposal , err ))
481484 return nil , err
@@ -705,6 +708,7 @@ func (s *Server) ShouldServe(
705708 // Check who is serving this tablet.
706709 tab := s .ServingTablet (tablet .Predicate )
707710 span .SetAttributes (attribute .String ("tablet_predicate" , tablet .Predicate ))
711+ span .SetAttributes (attribute .String ("tablet_label" , tablet .Label ))
708712 if tab != nil && ! tablet .Force {
709713 // If the existing tablet has a different label than requested, we need to re-route.
710714 // This can happen when a schema is applied with @label after the predicate was
@@ -919,6 +923,7 @@ func (s *Server) latestMembershipState(ctx context.Context) (*pb.MembershipState
919923}
920924
921925// groupLabel returns the label for a group (from first labeled member found)
926+ // Caller must hold the read lock.
922927func (s * Server ) groupLabel (gid uint32 ) string {
923928 s .AssertRLock ()
924929 group := s .state .Groups [gid ]
@@ -933,6 +938,14 @@ func (s *Server) groupLabel(gid uint32) string {
933938 return ""
934939}
935940
941+ // getGroupLabel is like groupLabel but handles its own locking.
942+ // Use this when calling from code that doesn't already hold the lock.
943+ func (s * Server ) getGroupLabel (gid uint32 ) string {
944+ s .RLock ()
945+ defer s .RUnlock ()
946+ return s .groupLabel (gid )
947+ }
948+
936949// labelGroupId the group ID that has the given label, or 0 if none
937950func (s * Server ) labelGroupId (label string ) (uint32 , error ) {
938951 s .AssertRLock ()
0 commit comments