github.com/oinume/lekcije@v0.0.0-20231017100347-5b4c5eb6ab24/backend/cmd/teacher_error_resetter/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"io"
     7  	"net/http"
     8  	"os"
     9  	"time"
    10  
    11  	"github.com/jinzhu/gorm"
    12  	"go.uber.org/zap"
    13  
    14  	"github.com/oinume/lekcije/backend/cli"
    15  	"github.com/oinume/lekcije/backend/domain/config"
    16  	"github.com/oinume/lekcije/backend/infrastructure/dmm_eikaiwa"
    17  	"github.com/oinume/lekcije/backend/logger"
    18  	"github.com/oinume/lekcije/backend/model"
    19  	"github.com/oinume/lekcije/backend/registry"
    20  )
    21  
    22  func main() {
    23  	m := &teacherErrorResetterMain{
    24  		outStream:  os.Stdout,
    25  		errStream:  os.Stderr,
    26  		db:         nil,
    27  		httpClient: nil,
    28  	}
    29  	if err := m.run(os.Args); err != nil {
    30  		cli.WriteError(m.errStream, err)
    31  		os.Exit(cli.ExitError)
    32  	}
    33  	os.Exit(cli.ExitOK)
    34  }
    35  
    36  type teacherErrorResetterMain struct {
    37  	outStream  io.Writer
    38  	errStream  io.Writer
    39  	db         *gorm.DB
    40  	httpClient *http.Client
    41  }
    42  
    43  const fetchErrorCount = 5
    44  
    45  func (m *teacherErrorResetterMain) run(args []string) error {
    46  	flagSet := flag.NewFlagSet("teacher_error_resetter", flag.ContinueOnError)
    47  	flagSet.SetOutput(m.errStream)
    48  	var (
    49  		concurrency = flagSet.Int("concurrency", 1, "Concurrency of lessonFetcher")
    50  		dryRun      = flagSet.Bool("dry-run", false, "Don't update database with fetched lessons")
    51  		logLevel    = flag.String("log-level", "info", "Log level")
    52  	)
    53  	if err := flagSet.Parse(args[1:]); err != nil {
    54  		return err
    55  	}
    56  
    57  	config.MustProcessDefault()
    58  	if m.db == nil {
    59  		db, err := model.OpenDB(config.DefaultVars.DBURL(), 1, config.DefaultVars.DebugSQL)
    60  		if err != nil {
    61  			cli.WriteError(os.Stderr, err)
    62  			os.Exit(1)
    63  		}
    64  		defer func() { _ = db.Close() }()
    65  		m.db = db
    66  	}
    67  
    68  	startedAt := time.Now().UTC()
    69  	appLogger := logger.NewAppLogger(os.Stderr, logger.NewLevel(*logLevel))
    70  	appLogger.Info("teacher_error_resetter started")
    71  	defer func() {
    72  		elapsed := time.Now().UTC().Sub(startedAt) / time.Millisecond
    73  		appLogger.Info("teacher_error_resetter finished", zap.Int("elapsed", int(elapsed)))
    74  	}()
    75  
    76  	ctx := context.Background()
    77  	teacherService := model.NewTeacherService(m.db)
    78  	teachers, err := teacherService.FindByFetchErrorCountGt(fetchErrorCount)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	mCountryList := registry.MustNewMCountryList(ctx, m.db.DB())
    84  	lessonFetcher := dmm_eikaiwa.NewLessonFetcher(m.httpClient, *concurrency, false, mCountryList, appLogger)
    85  	defer lessonFetcher.Close()
    86  	for _, t := range teachers {
    87  		if _, _, err := lessonFetcher.Fetch(ctx, uint(t.ID)); err != nil {
    88  			appLogger.Error("lessonFetcher.Fetch failed", zap.Uint32("id", t.ID), zap.Error(err))
    89  			continue
    90  		}
    91  		if *dryRun {
    92  			appLogger.Info("Skip teacher because of dry-run", zap.Uint32("id", t.ID))
    93  			continue
    94  		}
    95  		if err := teacherService.ResetFetchErrorCount(t.ID); err != nil {
    96  			appLogger.Error("teacherService.ResetFetchErrorCount failed", zap.Uint32("id", t.ID), zap.Error(err))
    97  			continue
    98  		}
    99  	}
   100  
   101  	return nil
   102  }