ronantakizawa/codereview-bench huggingface dataset:
Repository: dgraph-io/dgraph
File: ee/audit/interceptor.go (Go)

Code before:
// +build oss

/*
 * Copyright 2022 Dgraph Labs, Inc. and Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package audit

import (
	"context"
	"net/http"

	"google.golang.org/grpc"

	"github.com/dgraph-io/dgraph/graphql/schema"
)

func AuditRequestGRPC(ctx context.Context, req interface{},
	info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
	return handler(ctx, req)
}

func AuditRequestHttp(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, r)
	})
}

func AuditWebSockets(ctx context.Context, req *schema.Request) {
	return
}


Review comment (suggestion):
the import order should be, standard library, dgraph imports followed by all the other external imports

Code after:
//go:build oss
// +build oss

/*
 * Copyright 2023 Dgraph Labs, Inc. and Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package audit

import (
	"context"
	"net/http"

	"github.com/dgraph-io/dgraph/graphql/schema"

	"google.golang.org/grpc"
)

func AuditRequestGRPC(ctx context.Context, req interface{},
	info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
	return handler(ctx, req)
}

func AuditRequestHttp(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, r)
	})
}

func AuditWebSockets(ctx context.Context, req *schema.Request) {
	return
}
Repository: dgraph-io/dgraph
File: ee/audit/interceptor_ee.go (Go)

Code before:
			if subprotocol == "graphql-ws" {
				next.ServeHTTP(w, r)
				return
			}
		}

		rw := NewResponseWriter(w)
		var buf bytes.Buffer
		tee := io.TeeReader(r.Body, &buf)
		r.Body = ioutil.NopCloser(tee)
		next.ServeHTTP(rw, r)
		r.Body = ioutil.NopCloser(bytes.NewReader(buf.Bytes()))
		auditHttp(rw, r)
	})
}

func AuditWebSockets(ctx context.Context, req *schema.Request) {
	if atomic.LoadUint32(&auditEnabled) == 0 {
		return
	}

	namespace := uint64(0)
	var user string
	if token := req.Header.Get("X-Dgraph-AccessToken"); token != "" {
		user = getUser(token, false)
		namespace, _ = x.ExtractNamespaceFromJwt(token)
	} else if token := req.Header.Get("X-Dgraph-AuthToken"); token != "" {
		user = getUser(token, true)
	} else {
		user = getUser("", false)
	}

	ip := ""
	if peerInfo, ok := peer.FromContext(ctx); ok {
		ip, _, _ = net.SplitHostPort(peerInfo.Addr.String())
	}

	auditor.Audit(&AuditEvent{
		User:        user,
		Namespace:   namespace,
		ServerHost:  x.WorkerConfig.MyAddr,
		ClientHost:  ip,
		Endpoint:    "/graphql",
		ReqType:     WebSocket,
		Req:         truncate(req.Query, maxReqLength),
		Status:      http.StatusText(http.StatusOK),
		QueryParams: nil,
	})
}

func auditGrpc(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo) {

Review comment (bug):
The error is ignored here. Do you think that maybe it should be at least logged to WARN to give admins visibility into failed authn attempts in their audits?

Code after:
		for _, subprotocol := range websocket.Subprotocols(r) {
			if subprotocol == "graphql-ws" {
				next.ServeHTTP(w, r)
				return
			}
		}

		rw := NewResponseWriter(w)
		var buf bytes.Buffer
		tee := io.TeeReader(r.Body, &buf)
		r.Body = ioutil.NopCloser(tee)
		next.ServeHTTP(rw, r)
		r.Body = ioutil.NopCloser(bytes.NewReader(buf.Bytes()))
		auditHttp(rw, r)
	})
}

func AuditWebSockets(ctx context.Context, req *schema.Request) {
	if atomic.LoadUint32(&auditEnabled) == 0 {
		return
	}

	namespace := uint64(0)
	var err error
	var user string
	// TODO(anurag): X-Dgraph-AccessToken should be exported as a constant
	if token := req.Header.Get("X-Dgraph-AccessToken"); token != "" {
		user = getUser(token, false)
		namespace, err = x.ExtractNamespaceFromJwt(token)
		if err != nil {
			glog.Warningf("Error while auditing websockets: %s", err)
		}
	} else if token := req.Header.Get("X-Dgraph-AuthToken"); token != "" {
		user = getUser(token, true)
	} else {
		user = getUser("", false)
	}

	ip := ""
	if peerInfo, ok := peer.FromContext(ctx); ok {
		ip, _, _ = net.SplitHostPort(peerInfo.Addr.String())
	}

	auditor.Audit(&AuditEvent{
		User:        user,
		Namespace:   namespace,
		ServerHost:  x.WorkerConfig.MyAddr,
		ClientHost:  ip,
		Endpoint:    "/graphql",
		ReqType:     WebSocket,
		Req:         truncate(req.Query, maxReqLength),
Repository: dgraph-io/dgraph
File: x/jwt_helper.go (Go)

Code before:
		return "", err
	}
	userId, ok := claims["userid"].(string)
	if !ok {
		return "", errors.Errorf("userid in claims is not a string:%v", userId)
	}

	return userId, nil
}

func ExtractNamespaceFromJwt(jwtToken string) (uint64, error) {
	claims, err := ParseJWT(jwtToken)
	if err != nil {
		return 0, err
	}
	namespace, ok := claims["namespace"].(float64)
	if !ok {
		return 0, errors.Errorf("namespace in claims is not valid:%v", namespace)
	}
	return uint64(namespace), nil
}

func ExtractJWTNamespace(ctx context.Context) (uint64, error) {
	jwtString, err := ExtractJwt(ctx)
	if err != nil {
		return 0, err
	}
	return ExtractNamespaceFromJwt(jwtString)
}


Review comment (refactor):
I think this error should be wrapped so that some context other than the JWT-focused error message is returned, e.g., `return 0, errors.Wrap(err, "extracting namespace from JWT")`

Code after:
	if err != nil {
		return "", err
	}
	userId, ok := claims["userid"].(string)
	if !ok {
		return "", errors.Errorf("userid in claims is not a string:%v", userId)
	}

	return userId, nil
}

func ExtractNamespaceFromJwt(jwtToken string) (uint64, error) {
	claims, err := ParseJWT(jwtToken)
	if err != nil {
		return 0, errors.Wrap(err, "extracting namespace from JWT")
	}
	namespace, ok := claims["namespace"].(float64)
	if !ok {
		return 0, errors.Errorf("namespace in claims is not valid:%v", namespace)
	}
	return uint64(namespace), nil
}

func ExtractNamespaceFrom(ctx context.Context) (uint64, error) {
	jwtString, err := ExtractJwt(ctx)

	if err != nil {
		return 0, fmt.Errorf("extracting namespace from JWT %w", err)
	}
	return ExtractNamespaceFromJwt(jwtString)
}
Repository: dgraph-io/dgraph
File: dgraph/cmd/bulk/loader.go (Go)

Code before:
		cancel()
		if err == nil {
			return ts
		}
		fmt.Printf("Error communicating with dgraph alpha, retrying: %v", err)
		time.Sleep(time.Second)
	}
}

// leaseNamespace is called at the end of map phase. It leases the namespace ids till the maximum
// seen namespace id.
func (ld *loader) leaseNamespaces() {
	var maxNs uint64
	ld.namespaces.Range(func(key, value interface{}) bool {
		if ns := key.(uint64); ns > maxNs {
			maxNs = ns
		}
		return true
	})

	// If only the default namespace is seen, do nothing.
	if maxNs == 0 {
		return
	}

	if ld.zero != nil {
		client := pb.NewZeroClient(ld.zero)
		for {
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			ns, err := client.AssignIds(ctx, &pb.Num{Val: maxNs, Type: pb.Num_NS_ID})
			cancel()
			if err == nil {
				fmt.Printf("Assigned namespaces till %d\n", ns.GetEndId())
				return
			}
			fmt.Printf("Error communicating with dgraph zero, retrying: %v", err)
			time.Sleep(time.Second)
		}
	}

	for {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		_, end, err := ld.dg.AllocateTimestamps(ctx, maxNs)
		cancel()
		if err == nil {
			fmt.Printf("Assigned namespaces till %d\n", end)
			return
		}
		fmt.Printf("Error communicating with dgraph alpha, retrying: %v", err)
		time.Sleep(time.Second)
	}

Review comment (suggestion):
`leaseNamespaces` only handles the Zero client path and skips when `ld.zero` is nil, meaning no namespace leasing occurs when using the Alpha (`dgo`) connection. Add a fallback branch that uses `dg.AllocateTimestamps` to lease namespaces from Alpha.

Code after:
		cancel()
		if err == nil {
			return ts
		}
		fmt.Printf("Error communicating with dgraph alpha, retrying: %v", err)
		time.Sleep(time.Second)
	}
}

// leaseNamespace is called at the end of map phase. It leases the namespace ids till the maximum
// seen namespace id.
func (ld *loader) leaseNamespaces() {
	var maxNs uint64
	ld.namespaces.Range(func(key, value interface{}) bool {
		if ns := key.(uint64); ns > maxNs {
			maxNs = ns
		}
		return true
	})

	// If only the default namespace is seen, do nothing.
	if maxNs == 0 {
		return
	}

	if ld.zero != nil {
		client := pb.NewZeroClient(ld.zero)
		for {
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			ns, err := client.AssignIds(ctx, &pb.Num{Val: maxNs, Type: pb.Num_NS_ID})
			cancel()
			if err == nil {
				fmt.Printf("Assigned namespaces till %d\n", ns.GetEndId())
				return
			}
			fmt.Printf("Error communicating with dgraph zero, retrying: %v", err)
			time.Sleep(time.Second)
		}
	}

	if ld.dg != nil {
		for {
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			_, end, err := ld.dg.AllocateTimestamps(ctx, maxNs)
			cancel()
			if err == nil {
				fmt.Printf("Assigned namespaces till %d\n", end)
				return
			}
			fmt.Printf("Error communicating with dgraph alpha, retrying: %v", err)
			time.Sleep(time.Second)
Repository: dgraph-io/dgraph
File: tok/partitioned_hnsw/partitioned_hnsw.go (Go)

Code before:
	if len(res) > 0 {
		return res
	}

	if ph.buildPass < ph.partition.NumPasses() {
		ph.partition.EndBuildPass()
	}
	return []int{}
}

func (ph *partitionedHNSW[T]) Insert(ctx context.Context, txn index.CacheType, uid uint64, vec []T) ([]*index.KeyValue, error) {
	if len(vec) == 0 {
		ph.vectorDimension = len(vec)
	}

	if len(vec) != ph.vectorDimension {
		return nil, fmt.Errorf("connot insert vector length of %d vector lenth should be %d", len(vec), ph.vectorDimension)
	}

	index, err := ph.partition.FindIndexForInsert(vec)
	if err != nil {
		return nil, err
	}
	return ph.clusterMap[index].Insert(ctx, txn, uid, vec)
}

func (ph *partitionedHNSW[T]) Search(ctx context.Context, txn index.CacheType, query []T, maxResults int, filter index.SearchFilter[T]) ([]uint64, error) {
	indexes, err := ph.partition.FindIndexForSearch(query)
	if err != nil {
		return nil, err
	}
	res := []uint64{}
	mutex := &sync.Mutex{}
	var wg sync.WaitGroup
	for _, index := range indexes {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			ids, err := ph.clusterMap[i].Search(ctx, txn, query, maxResults, filter)
			if err != nil {
				return
			}
			mutex.Lock()
			res = append(res, ids...)
			mutex.Unlock()
		}(index)
	}
	wg.Wait()
	return ph.clusterMap[0].MergeResults(ctx, txn, res, query, maxResults, filter)
}


Review comment (suggestion):
some typos, consider replacing the format string with `can not insert vector length of %d, vector length should be %d`

Code after:
				continue
			}
			ph.clusterMap[i].EndBuild()
			res = append(res, i)
		}
	}

	ph.buildPass += 1

	if len(res) > 0 {
		return res
	}

	if ph.buildPass < ph.partition.NumPasses() {
		ph.partition.EndBuildPass()
	}
	return []int{}
}

func (ph *partitionedHNSW[T]) Insert(ctx context.Context, txn index.CacheType, uid uint64, vec []T) ([]*index.KeyValue, error) {
	if len(vec) == 0 {
		ph.vectorDimension = len(vec)
	}

	if len(vec) != ph.vectorDimension {
		return nil, fmt.Errorf("connot insert vector length of %d vector lenth should be %d", len(vec), ph.vectorDimension)
	}

	index, err := ph.partition.FindIndexForInsert(vec)
	if err != nil {
		return nil, err
	}
	return ph.clusterMap[index].Insert(ctx, txn, uid, vec)
}

func (ph *partitionedHNSW[T]) Search(ctx context.Context, txn index.CacheType, query []T, maxResults int, filter index.SearchFilter[T]) ([]uint64, error) {
	indexes, err := ph.partition.FindIndexForSearch(query)
	if err != nil {
		return nil, err
	}
	res := []uint64{}
	mutex := &sync.Mutex{}
	var wg sync.WaitGroup
	for _, index := range indexes {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			ids, err := ph.clusterMap[i].Search(ctx, txn, query, maxResults, filter)
			if err != nil {
				return
			}
Repository: dgraph-io/dgraph
File: dgraphtest/local_cluster.go (Go)

Code before:
			return err
		}
		if err := c.waitUntilGraphqlHealthCheck(); err != nil {
			return err
		}
		return nil
	}

	return fmt.Errorf("health failed, cluster took too long to come up [%v]", endpoint)
}

func (c *LocalCluster) waitUntilLogin() error {
	if !c.conf.acl {
		return nil
	}

	client, cleanup, err := c.Client()
	if err != nil {
		return errors.Wrap(err, "error setting up a client")
	}
	defer cleanup()

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	defer cancel()
	for attempt := range 10 {
		err = client.Login(ctx, dgraphapi.DefaultUser, dgraphapi.DefaultPassword)
		if err == nil {
			log.Printf("[INFO] login succeeded")
			return nil
		}
		if attempt > 10 {
			log.Printf("[WARNING] error trying to login: %v", err)
		}
		time.Sleep(waitDurBeforeRetry)
	}
	return errors.Wrap(err, "error during login")
}

func (c *LocalCluster) waitUntilGraphqlHealthCheck() error {
	hc, err := c.HTTPClient()
	if err != nil {
		return errors.Wrap(err, "error creating http client while graphql health check")
	}
	if c.conf.acl {
		if err := hc.LoginIntoNamespace(dgraphapi.DefaultUser, dgraphapi.DefaultPassword, x.RootNamespace); err != nil {
			return errors.Wrap(err, "error during login while graphql health check")
		}
	}

	for range 10 {
		// we do this because before v21, we used to propose the initial schema to the cluster.

Review comment (suggestion):
The variable `err` is being assigned but not declared in this scope. It should use `:=` for declaration or `err` should be declared earlier in the function.

Code after:
			return err
		}
		if err := c.waitUntilGraphqlHealthCheck(); err != nil {
			return err
		}
		return nil
	}

	return fmt.Errorf("health failed, cluster took too long to come up [%v]", endpoint)
}

func (c *LocalCluster) waitUntilLogin() error {
	if !c.conf.acl {
		return nil
	}

	client, cleanup, err := c.Client()
	if err != nil {
		return errors.Wrap(err, "error setting up a client")
	}
	defer cleanup()

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	defer cancel()
	for attempt := range 10 {
		err = client.Login(ctx, dgraphapi.DefaultUser, dgraphapi.DefaultPassword)
		if err == nil {
			log.Printf("[INFO] login succeeded")
			return nil
		}
		if attempt > 10 {
			log.Printf("[WARNING] error trying to login: %v", err)
		}
		time.Sleep(waitDurBeforeRetry)
	}
	return errors.Wrap(err, "error during login")
}

func (c *LocalCluster) waitUntilGraphqlHealthCheck() error {
	hc, err := c.HTTPClient()
	if err != nil {
		return errors.Wrap(err, "error creating http client while graphql health check")
	}
	if c.conf.acl {
		if err := hc.LoginIntoNamespace(dgraphapi.DefaultUser, dgraphapi.DefaultPassword, x.RootNamespace); err != nil {
			return errors.Wrap(err, "error during login while graphql health check")
		}
	}

	for range 10 {
		// Sleep for a second before retrying
Repository: dgraph-io/dgraph
File: dgraphtest/load.go (Go)

Code before:
}

func (d *Dataset) GqlSchemaPath() string {
	return d.ensureFile(fmt.Sprintf("%s.gql_schema", d.name))
}

func (d *Dataset) ensureFile(filename string) string {
	fullPath := filepath.Join(datasetFilesPath, filename)
	if exists, _ := fileExists(fullPath); !exists {
		url, ok := datafiles[filename]
		if !ok {
			panic(fmt.Sprintf("dataset file %s not found in datafiles map", filename))
		}
		if err := downloadFile(filename, url); err != nil {
			panic(fmt.Sprintf("failed to download %s: %v", filename, err))
		}
	}
	return fullPath
}

func downloadFile(fname, url string) error {
	cmd := exec.Command("wget", "-O", fname, url)
	cmd.Dir = datasetFilesPath

	if _, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("error downloading file %s: %s", fname, err.Error())
	}
	return nil
}


Review comment (suggestion):
```suggestion
		return fmt.Errorf("error downloading file %s: %w", fname, err)
```

If you meant to wrap the error, you should use `%w`.

Code after:
}

func (d *Dataset) GqlSchemaPath() string {
	return d.ensureFile(fmt.Sprintf("%s.gql_schema", d.name))
}

func (d *Dataset) ensureFile(filename string) string {
	fullPath := filepath.Join(datasetFilesPath, filename)
	if exists, _ := fileExists(fullPath); !exists {
		url, ok := datafiles[filename]
		if !ok {
			panic(fmt.Sprintf("dataset file %s not found in datafiles map", filename))
		}
		if err := downloadFile(filename, url); err != nil {
			panic(fmt.Sprintf("failed to download %s: %v", filename, err))
		}
	}
	return fullPath
}

func downloadFile(fname, url string) error {
	cmd := exec.Command("wget", "-O", fname, url)
	cmd.Dir = datasetFilesPath

	if _, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("error downloading file %s: %w", fname, err)
	}
	return nil
}
Repository: didi/nightingale
File: src/server/engine/rule.go (Go)

Code before:

func (rh *RuleHolder) SyncAlertRules() {
	ids := memsto.AlertRuleCache.GetRuleIds()
	alertRules := make(map[string]RuleContext)
	externalAllRules := make(map[string]*AlertRuleContext)
	for _, id := range ids {
		rule := memsto.AlertRuleCache.Get(id)
		if rule == nil {
			continue
		}

		ruleClusters := strings.Fields(rule.Cluster)
		for _, cluster := range ruleClusters {
			// hash ring not hit
			if !naming.ClusterHashRing.IsHit(cluster, fmt.Sprintf("%d", rule.Id), config.C.Heartbeat.Endpoint) {
				continue
			}

			if rule.IsPrometheusRule() {
				// 正常的告警规则
				alertRule := NewAlertRuleContext(rule, cluster)
				alertRules[alertRule.Hash()] = alertRule
			} else {
				// 如果 rule 不是通过 prometheus engine 来告警的，则创建为 externalRule
				externalRule := NewAlertRuleContext(rule, cluster)
				externalAllRules[externalRule.Hash()] = externalRule
			}
		}
	}

	for hash, rule := range alertRules {
		if _, has := rh.alertRules[hash]; !has {
			rule.Prepare()
			rule.Start()
			rh.alertRules[hash] = rule
		}
	}

	for hash, rule := range rh.alertRules {
		if _, has := alertRules[hash]; !has {
			rule.Stop()
			delete(rh.alertRules, hash)
		}
	}

	rh.externalLock.Lock()
	for hash, rule := range externalAllRules {
		if _, has := rh.externalAlertRules[hash]; !has {
			rule.Prepare()
			rh.externalAlertRules[hash] = rule
		}

Review comment (suggestion):
这里使用 `externalRule.Hash()` 的话， [GetExternalAlertRule](https://github.com/ccfos/nightingale/blob/072f1bd51f5c667a1ea6c85d3d963ec93637e4bd/src/server/engine/rule.go#L160) 也需要更新下

Code after:
func (rh *RuleHolder) SyncAlertRules() {
	ids := memsto.AlertRuleCache.GetRuleIds()
	alertRules := make(map[string]RuleContext)
	externalAllRules := make(map[string]*AlertRuleContext)
	for _, id := range ids {
		rule := memsto.AlertRuleCache.Get(id)
		if rule == nil {
			continue
		}
		
		
		ruleClusters := config.ReaderClients.Hit(rule.Cluster)
		if !rule.IsPrometheusRule() {
		        // 非 Prometheus 的规则, 不支持 $all, 直接从 rule.Cluster 解析
			ruleClusters = strings.Fields(rule.Cluster)
		}
		
		
		for _, cluster := range ruleClusters {
			// hash ring not hit
			if !naming.ClusterHashRing.IsHit(cluster, fmt.Sprintf("%d", rule.Id), config.C.Heartbeat.Endpoint) {
				continue
			}

			if rule.IsPrometheusRule() {
				// 正常的告警规则
				alertRule := NewAlertRuleContext(rule, cluster)
				alertRules[alertRule.Hash()] = alertRule
			} else {
				// 如果 rule 不是通过 prometheus engine 来告警的，则创建为 externalRule
				externalRule := NewAlertRuleContext(rule, cluster)
				externalAllRules[externalRule.Key()] = externalRule
			}
		}
	}

	for hash, rule := range alertRules {
		if _, has := rh.alertRules[hash]; !has {
			rule.Prepare()
			rule.Start()
			rh.alertRules[hash] = rule
		}
	}

	for hash, rule := range rh.alertRules {
		if _, has := alertRules[hash]; !has {
			rule.Stop()
			delete(rh.alertRules, hash)
		}
	}
Repository: didi/nightingale
File: center/router/router_alert_cur_event.go (Go)

Code before:
	dsIds := queryDatasourceIds(c)

	prod := ginx.QueryStr(c, "prods", "")
	if prod == "" {
		prod = ginx.QueryStr(c, "rule_prods", "")
	}

	prods := []string{}
	if prod != "" {
		prods = strings.Split(prod, ",")
	}

	cate := ginx.QueryStr(c, "cate", "$all")
	cates := []string{}
	if cate != "$all" {
		cates = strings.Split(cate, ",")
	}

	ruleId := ginx.QueryInt64(c, "rid", 0)
	gids, err := getUserGroupIds(c, rt, myGroups)

	bgids, err := GetBusinessGroupIds(c, rt.Ctx, rt.Center.EventHistoryGroupView)
	ginx.Dangerous(err)

	total, err := models.AlertCurEventTotal(rt.Ctx, prods, bgids, stime, etime, severity, dsIds,
		cates, ruleId, query, gids, myGroups)
	ginx.Dangerous(err)

	list, err := models.AlertCurEventsGet(rt.Ctx, prods, bgids, stime, etime, severity, dsIds,
		cates, ruleId, query, limit, ginx.Offset(c, limit), gids, myGroups)
	ginx.Dangerous(err)

	cache := make(map[int64]*models.UserGroup)

	for i := 0; i < len(list); i++ {
		list[i].FillNotifyGroups(rt.Ctx, cache)
	}

	ginx.NewRender(c).Data(gin.H{
		"list":  list,
		"total": total,
	}, nil)
}

func (rt *Router) alertCurEventDel(c *gin.Context) {
	var f idsForm
	ginx.BindJSON(c, &f)
	f.Verify()

	rt.checkCurEventBusiGroupRWPermission(c, f.Ids)


Review comment (suggestion):
Here, a single parameter `gids` will suffice, and later, you can determine whether to add it to the SQL query based on whether the length of `gids` is greater than 0

Code after:
// 列表方式，拉取活跃告警
func (rt *Router) alertCurEventsList(c *gin.Context) {
	stime, etime := getTimeRange(c)
	severity := ginx.QueryInt(c, "severity", -1)
	query := ginx.QueryStr(c, "query", "")
	limit := ginx.QueryInt(c, "limit", 20)
	myGroups := ginx.QueryBool(c, "my_groups", false) // 是否只看自己组，默认false

	dsIds := queryDatasourceIds(c)

	prod := ginx.QueryStr(c, "prods", "")
	if prod == "" {
		prod = ginx.QueryStr(c, "rule_prods", "")
	}

	prods := []string{}
	if prod != "" {
		prods = strings.Split(prod, ",")
	}

	cate := ginx.QueryStr(c, "cate", "$all")
	cates := []string{}
	if cate != "$all" {
		cates = strings.Split(cate, ",")
	}

	ruleId := ginx.QueryInt64(c, "rid", 0)

	var gids []int64
	var err error
	if myGroups {
		gids, err = getUserGroupIds(c, rt, myGroups)
		ginx.Dangerous(err)
		if len(gids) == 0 {
			gids = append(gids, -1)
		}
	}

	bgids, err := GetBusinessGroupIds(c, rt.Ctx, rt.Center.EventHistoryGroupView)
	ginx.Dangerous(err)

	total, err := models.AlertCurEventTotal(rt.Ctx, prods, bgids, stime, etime, severity, dsIds,
		cates, ruleId, query, gids)
	ginx.Dangerous(err)

	list, err := models.AlertCurEventsGet(rt.Ctx, prods, bgids, stime, etime, severity, dsIds,
		cates, ruleId, query, limit, ginx.Offset(c, limit), gids)
	ginx.Dangerous(err)

	cache := make(map[int64]*models.UserGroup)