git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/selfupdate/autoupdate.go (about)

     1  package selfupdate
     2  
     3  import (
     4  	"context"
     5  	"log/slog"
     6  	"math/rand"
     7  	"os"
     8  	"time"
     9  
    10  	"git.sr.ht/~pingoo/stdx/log/slogx"
    11  )
    12  
    13  const (
    14  	updatedExecutableOpenFlags = os.O_WRONLY | os.O_CREATE | os.O_TRUNC
    15  )
    16  
    17  func (updater *Updater) RunAutoupdateInBackground(ctx context.Context) {
    18  	logger := slogx.FromCtx(ctx)
    19  	var err error
    20  	var manifest ChannelManifest
    21  
    22  	for {
    23  		// sleep for autoupdateInterval + 10 seconds jitter
    24  		waitFor := rand.Int63n(10) + updater.autoupdateInterval
    25  
    26  		select {
    27  		case <-ctx.Done():
    28  			if updater.verbose {
    29  				logger.Info("selfupdate: stopping")
    30  			}
    31  
    32  			return
    33  		case <-time.After(time.Duration(waitFor) * time.Second):
    34  			if updater.verbose {
    35  				logger.Info("selfupdate: checking for update")
    36  			}
    37  
    38  			manifest, err = updater.CheckUpdate(ctx)
    39  			if err != nil {
    40  				logger.Warn("selfupdate: error while checking for update", slogx.Err(err))
    41  				continue
    42  			}
    43  
    44  			if updater.UpdateAvailable() {
    45  				logger = logger.With(slog.String("selfupdate_new_version", manifest.Version))
    46  				if updater.verbose {
    47  					logger.Info("selfupdate: a new update is available")
    48  				}
    49  
    50  				err = updater.Update(ctx, manifest)
    51  				if err != nil {
    52  					logger.Warn("selfupdate: installing new version", slogx.Err(err))
    53  					continue
    54  				}
    55  
    56  				if updater.verbose {
    57  					logger.Info("selfupdate: new version successfully installed")
    58  				}
    59  
    60  				updater.Updated <- struct{}{}
    61  			}
    62  		}
    63  	}
    64  }