1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
15 "git.curoverse.com/arvados.git/sdk/go/arvados"
16 "git.curoverse.com/arvados.git/sdk/go/ctxlog"
17 "github.com/sirupsen/logrus"
20 // RunOptions controls runtime behavior. The flags/options that belong
21 // here are the ones that are useful for interactive use. For example,
22 // "CommitTrash" is a runtime option rather than a config item because
23 // it invokes a troubleshooting feature rather than expressing how
24 // balancing is meant to be done at a given site.
26 // RunOptions fields are controlled by command line flags.
27 type RunOptions struct {
31 Logger logrus.FieldLogger
32 Dumper logrus.FieldLogger
34 // SafeRendezvousState from the most recent balance operation,
35 // or "" if unknown. If this changes from one run to the next,
36 // we need to watch out for races. See
37 // (*Balancer)ClearTrashLists.
38 SafeRendezvousState string
43 Cluster *arvados.Cluster
44 ArvClient *arvados.Client
48 Logger logrus.FieldLogger
49 Dumper logrus.FieldLogger
52 // CheckHealth implements service.Handler.
53 func (srv *Server) CheckHealth() error {
57 // Start sets up and runs the balancer.
58 func (srv *Server) Start(ctx context.Context) {
59 if srv.RunOptions.Logger == nil {
60 srv.RunOptions.Logger = ctxlog.FromContext(ctx)
63 srv.Logger = srv.RunOptions.Logger
64 srv.Dumper = srv.RunOptions.Dumper
67 if srv.RunOptions.Once {
70 err = srv.runForever(nil)
77 func (srv *Server) run() (*Balancer, error) {
82 LostBlocksFile: srv.Cluster.Collections.BlobMissingReport,
85 srv.RunOptions, err = bal.Run(srv.ArvClient, srv.Cluster, srv.RunOptions)
89 // RunForever runs forever, or (for testing purposes) until the given
90 // stop channel is ready to receive.
91 func (srv *Server) runForever(stop <-chan interface{}) error {
94 ticker := time.NewTicker(time.Duration(srv.Cluster.Collections.BalancePeriod))
96 // The unbuffered channel here means we only hear SIGUSR1 if
97 // it arrives while we're waiting in select{}.
98 sigUSR1 := make(chan os.Signal)
99 signal.Notify(sigUSR1, syscall.SIGUSR1)
101 logger.Printf("starting up: will scan every %v and on SIGUSR1", srv.Cluster.Collections.BalancePeriod)
104 if !srv.RunOptions.CommitPulls && !srv.RunOptions.CommitTrash {
105 logger.Print("WARNING: Will scan periodically, but no changes will be committed.")
106 logger.Print("======= Consider using -commit-pulls and -commit-trash flags.")
111 logger.Print("run failed: ", err)
113 logger.Print("run succeeded")
121 logger.Print("timer went off")
123 logger.Print("received SIGUSR1, resetting timer")
124 // Reset the timer so we don't start the N+1st
125 // run too soon after the Nth run is triggered
128 ticker = time.NewTicker(time.Duration(srv.Cluster.Collections.BalancePeriod))
130 logger.Print("starting next run")