<commit_before>package modd

import (
	"os"
	"os/exec"
	"sync"
	"time"

	"github.com/cortesi/modd/conf"
	"github.com/cortesi/modd/shell"
	"github.com/cortesi/modd/varcmd"
	"github.com/cortesi/termlog"
)

const (
	// MinRestart is the minimum amount of time between daemon restarts
	MinRestart = 500 * time.Millisecond
	// MulRestart is the exponential backoff multiplier applied when the daemon exits uncleanly
	MulRestart = 2
	// MaxRestart is the maximum amount of time between daemon restarts
	MaxRestart = 8 * time.Second
)

// A single daemon
type daemon struct {
	conf  conf.Daemon
	indir string

	running bool
	ex      *shell.Executor
	log     termlog.Stream
	shell   string
	stop    bool
	sync.Mutex
}

func (d *daemon) Run() {
	ex, err := shell.NewExecutor(d.shell, d.conf.Command, d.indir)
	if err != nil {
		d.log.Shout("Could not create executor: %s", err)
	}
	d.ex = ex

	var lastStart time.Time
	delay := MinRestart
	for d.stop != true {
		if !lastStart.IsZero() {
			d.log.Notice(">> sleeping... %#v", delay)
			time.Sleep(delay)
		}
		d.log.Notice(">> starting...")
		lastStart = time.Now()
		err, pstate := ex.Run(d.log, false)

		if err != nil {<commit_msg>Nicer output for restart backoff<commit_after>package modd

import (
	"os"
	"os/exec"
	"sync"
	"time"

	"github.com/cortesi/modd/conf"
	"github.com/cortesi/modd/shell"
	"github.com/cortesi/modd/varcmd"
	"github.com/cortesi/termlog"
)

const (
	// MinRestart is the minimum amount of time between daemon restarts
	MinRestart = 500 * time.Millisecond
	// MulRestart is the exponential backoff multiplier applied when the daemon exits uncleanly
	MulRestart = 2
	// MaxRestart is the maximum amount of time between daemon restarts
	MaxRestart = 8 * time.Second
)

// A single daemon
type daemon struct {
	conf  conf.Daemon
	indir string

	running bool
	ex      *shell.Executor
	log     termlog.Stream
	shell   string
	stop    bool
	sync.Mutex
}

func (d *daemon) Run() {
	ex, err := shell.NewExecutor(d.shell, d.conf.Command, d.indir)
	if err != nil {
		d.log.Shout("Could not create executor: %s", err)
	}
	d.ex = ex

	var lastStart time.Time
	delay := MinRestart
	for d.stop != true {
		if delay > MinRestart {
			d.log.Notice(">> restart backoff... %dms", delay/time.Millisecond)
		}
		if !lastStart.IsZero() {
			time.Sleep(delay)
		}
		d.log.Notice(">> starting...")
		lastStart = time.Now()
		err, pstate := ex.Run(d.log, false)

		if err != nil {
{'fraction_non_alphanumeric': 0.1254125412541254, 'fraction_numerical': 0.004125412541254125, 'mean_word_length': 3.2693661971830985, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1000575', 'n_tokens_mistral': 960, 'n_tokens_neox': 915, 'n_words': 246}