github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/syz-cluster/pkg/reporter/generator.go (about)

     1  // Copyright 2025 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package reporter
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"time"
    10  
    11  	"github.com/google/syzkaller/syz-cluster/pkg/api"
    12  	"github.com/google/syzkaller/syz-cluster/pkg/app"
    13  	"github.com/google/syzkaller/syz-cluster/pkg/db"
    14  )
    15  
    16  const (
    17  	// The frequency of checking for new results to report.
    18  	generateReportsPeriod = time.Minute
    19  	// How many result to check at each loop iteration.
    20  	generateReportsLimit = 5
    21  	// Consider only recently finished sessions.
    22  	// It helps optimize DB queries + older sessions are not relevant anyway.
    23  	relevantReportAge = time.Hour * 24 * 3
    24  )
    25  
    26  type ReportGenerator struct {
    27  	sessionRepo *db.SessionRepository
    28  	reportRepo  *db.ReportRepository
    29  }
    30  
    31  func NewGenerator(env *app.AppEnvironment) *ReportGenerator {
    32  	return &ReportGenerator{
    33  		sessionRepo: db.NewSessionRepository(env.Spanner),
    34  		reportRepo:  db.NewReportRepository(env.Spanner),
    35  	}
    36  }
    37  
    38  func (rg *ReportGenerator) Loop(ctx context.Context) {
    39  	for {
    40  		err := rg.Process(ctx, generateReportsLimit)
    41  		if err != nil {
    42  			app.Errorf("failed to process reports: %v", err)
    43  		}
    44  		select {
    45  		case <-ctx.Done():
    46  			return
    47  		case <-time.After(generateReportsPeriod):
    48  		}
    49  	}
    50  }
    51  
    52  func (rg *ReportGenerator) Process(ctx context.Context, limit int) error {
    53  	list, err := rg.sessionRepo.MissingReportList(ctx,
    54  		time.Now().Add(-relevantReportAge), limit)
    55  	if err != nil {
    56  		return fmt.Errorf("failed to query sessions: %w", err)
    57  	}
    58  	for _, session := range list {
    59  		report := &db.SessionReport{
    60  			SessionID:  session.ID,
    61  			Moderation: true,
    62  			Reporter:   api.LKMLReporter,
    63  		}
    64  		err := rg.reportRepo.Insert(ctx, report)
    65  		if err != nil {
    66  			return fmt.Errorf("failed to insert the report: %w", err)
    67  		}
    68  	}
    69  	return nil
    70  }