<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/go-kit/kit/log/level"
	"github.com/goph/emperror"
	"github.com/goph/healthz"
	"github.com/goph/serverz"
	"github.com/goph/stdlib/ext"
	"github.com/kelseyhightower/envconfig"
)

func main() {
	config := &configuration{}

	// Load configuration from environment
	err := envconfig.Process("", config)
	if err != nil {
		panic(err)
	}

	// Load configuration from flags
	flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	config.flags(flags)
	flags.Parse(os.Args[1:])

	if config.Daemon && config.DaemonSchedule <= 0 {
		panic("Daemon mode requires the DAEMON_SCHEDULE environment variable to be set.")
	}

	// Create a new logger
	logger := newLogger(config)
	defer ext.Close(logger)

	// Create a new error handler
	errorHandler := newErrorHandler(config, logger)
	defer ext.Close(errorHandler)

	// Register error handler to recover from panics
	defer emperror.HandleRecover(errorHandler)

	healthCollector := healthz.Collector{}
	tracer := newTracer(config)
	metricsReporter := newMetricsReporter(config)

	// Application context
	appCtx := &application{
		config:          config,
		logger:          logger,
		errorHandler:    errorHandler,
		healthCollector: healthCollector,
		tracer:          tracer,
		metricsReporter: metricsReporter,
	}

	mode := "cron"
	if config.Daemon {
		mode = "daemon"
	}

	level.Info(logger).Log(
		"msg", fmt.Sprintf("Starting %s", FriendlyServiceName),
		"version", Version,
		"commitHash", CommitHash,
		"buildDate", BuildDate,
		"environment", config.Environment,
		"mode", mode,
	)

	job := newJob(appCtx)
	defer ext.Close(job)

	if false == config.Daemon {
		job.Run()
	} else {
		serverQueue := serverz.NewQueue(&serverz.Manager{Logger: logger})

		if config.Debug {
			debugServer := newDebugServer(logger)
			serverQueue.Append(debugServer, config.DebugAddr)
			defer debugServer.Close()
		}

		healthServer, status := newHealthServer(appCtx)
		serverQueue.Prepend(healthServer, config.HealthAddr)
		defer healthServer.Close()

		errChan := serverQueue.Start()

		ticker := time.NewTicker(config.DaemonSchedule)
		quit := make(chan struct{})

		go func() {
			for {
				select {
				case <-quit:
					return
				case <-ticker.C:
					go job.Run()
				}
			}
		}()

		signalChan := make(chan os.Signal, 1)
		signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

	MainLoop:
		for {
			select {
			case err := <-errChan:
				status.SetStatus(healthz.Unhealthy)
				close(quit)
				level.Debug(logger).Log("msg", "Error received from error channel")
				emperror.HandleIfErr(errorHandler, err)

				// Break the loop, proceed with regular shutdown
				break MainLoop
			case s := <-signalChan:
				level.Info(logger).Log("msg", fmt.Sprintf("Captured %v", s))
				status.SetStatus(healthz.Unhealthy)
				close(quit)

				level.Debug(logger).Log(
					"msg", "Shutting down with timeout",
					"timeout", config.ShutdownTimeout,
				)

				ctx, cancel := context.WithTimeout(context.Background(), config.ShutdownTimeout)

				err := serverQueue.Stop(ctx)
				if err != nil {
					errorHandler.Handle(err)
				}

				// Cancel context if shutdown completed earlier
				cancel()

				// Break the loop, proceed with regular shutdown
				break MainLoop
			}
		}
	}
}<commit_msg>Always run health and debug servers<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/go-kit/kit/log/level"
	"github.com/goph/emperror"
	"github.com/goph/healthz"
	"github.com/goph/serverz"
	"github.com/goph/stdlib/ext"
	"github.com/kelseyhightower/envconfig"
)

func main() {
	config := &configuration{}

	// Load configuration from environment
	err := envconfig.Process("", config)
	if err != nil {
		panic(err)
	}

	// Load configuration from flags
	flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	config.flags(flags)
	flags.Parse(os.Args[1:])

	if config.Daemon && config.DaemonSchedule <= 0 {
		panic("Daemon mode requires the DAEMON_SCHEDULE environment variable to be set.")
	}

	// Create a new logger
	logger := newLogger(config)
	defer ext.Close(logger)

	// Create a new error handler
	errorHandler := newErrorHandler(config, logger)
	defer ext.Close(errorHandler)

	// Register error handler to recover from panics
	defer emperror.HandleRecover(errorHandler)

	healthCollector := healthz.Collector{}
	tracer := newTracer(config)
	metricsReporter := newMetricsReporter(config)

	// Application context
	appCtx := &application{
		config:          config,
		logger:          logger,
		errorHandler:    errorHandler,
		healthCollector: healthCollector,
		tracer:          tracer,
		metricsReporter: metricsReporter,
	}

	serverQueue := serverz.NewQueue(&serverz.Manager{Logger: logger})

	mode := "cron"
	if config.Daemon {
		mode = "daemon"
	}

	level.Info(logger).Log(
		"msg", fmt.Sprintf("Starting %s", FriendlyServiceName),
		"version", Version,
		"commitHash", CommitHash,
		"buildDate", BuildDate,
		"environment", config.Environment,
		"mode", mode,
	)

	job := newJob(appCtx)
	defer ext.Close(job)

	if config.Debug {
		debugServer := newDebugServer(logger)
		serverQueue.Append(debugServer, config.DebugAddr)
		defer debugServer.Close()
	}

	healthServer, status := newHealthServer(appCtx)
	serverQueue.Prepend(healthServer, config.HealthAddr)
	defer healthServer.Close()

	errChan := serverQueue.Start()

	// Necessary for daemon mode
	quit := make(chan struct{})

	if false == config.Daemon {
		job.Run()
	} else {
		ticker := time.NewTicker(config.DaemonSchedule)

		go func() {
			for {
				select {
				case <-quit:
					return
				case <-ticker.C:
					go job.Run()
				}
			}
		}()
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

MainLoop:
	for {
		select {
		case err := <-errChan:
			status.SetStatus(healthz.Unhealthy)
			close(quit)
			level.Debug(logger).Log("msg", "Error received from error channel")
			emperror.HandleIfErr(errorHandler, err)

			// Break the loop, proceed with regular shutdown
			break MainLoop
		case s := <-signalChan:
			level.Info(logger).Log("msg", fmt.Sprintf("Captured %v", s))
			status.SetStatus(healthz.Unhealthy)
			close(quit)

			level.Debug(logger).Log(
				"msg", "Shutting down with timeout",
				"timeout", config.ShutdownTimeout,
			)

			ctx, cancel := context.WithTimeout(context.Background(), config.ShutdownTimeout)

			err := serverQueue.Stop(ctx)
			if err != nil {
				errorHandler.Handle(err)
			}

			// Cancel context if shutdown completed earlier
			cancel()

			// Break the loop, proceed with regular shutdown
			break MainLoop
		}
	}
}
{'fraction_non_alphanumeric': 0.12928325602274426, 'fraction_numerical': 0.0011970671853957803, 'mean_word_length': 3.6839523475823404, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, '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': '1114924', 'n_tokens_mistral': 2549, 'n_tokens_neox': 2210, 'n_words': 497}