func (bctl *BucketCtl) SetGroupsTimeout(s *elliptics.Session, bucket *Bucket, key string) { // sort groups by defrag state, increase timeout if needed groups := make([]uint32, 0) defrag_groups := make([]uint32, 0) timeout := 30 for group_id, sg := range bucket.Group { sb, err := sg.FindStatBackendKey(s, key, group_id) if err != nil { continue } if sb.DefragState != 0 { defrag_groups = append(defrag_groups, group_id) } else { groups = append(groups, group_id) } } // Not being defragmented backends first, then those which are currently being defragmented groups = append(groups, defrag_groups...) if len(groups) == len(defrag_groups) { timeout = 90 } // if there are no backends being defragmented, use weights to mix read states // if there are such backends, use strict order and read from non-defragmented backends first ioflags := elliptics.IOflag(bctl.Conf.Proxy.ReaderIOFlags) | s.GetIOflags() if len(defrag_groups) == 0 { ioflags |= elliptics.DNET_IO_FLAGS_MIX_STATES } s.SetIOflags(ioflags) // there are no stats for bucket groups, use what we have in metadata if len(groups) == 0 { groups = bucket.Meta.Groups } s.SetGroups(groups) s.SetTimeout(timeout) }