Add flags to modify max concurrency directory and file scans

This commit is contained in:
Seednode 2023-09-26 03:34:50 -05:00
parent 974a4c79fc
commit a1d041dedc
4 changed files with 83 additions and 73 deletions

View File

@ -112,35 +112,37 @@ Usage:
roulette <path> [path]... [flags] roulette <path> [path]... [flags]
Flags: Flags:
-a, --all enable all supported file types -a, --all enable all supported file types
--audio enable support for audio files --audio enable support for audio files
-b, --bind string address to bind to (default "0.0.0.0") -b, --bind string address to bind to (default "0.0.0.0")
-c, --cache generate directory cache at startup -c, --cache generate directory cache at startup
--cache-file string path to optional persistent cache file --cache-file string path to optional persistent cache file
--case-sensitive use case-sensitive matching for filters --case-sensitive use case-sensitive matching for filters
--code enable support for source code files --code enable support for source code files
--code-theme string theme for source code syntax highlighting (default "solarized-dark256") --code-theme string theme for source code syntax highlighting (default "solarized-dark256")
--exit-on-error shut down webserver on error, instead of just printing the error --exit-on-error shut down webserver on error, instead of just printing the error
-f, --filter enable filtering -f, --filter enable filtering
--flash enable support for shockwave flash files (via ruffle.rs) --flash enable support for shockwave flash files (via ruffle.rs)
--handlers display registered handlers (for debugging) --handlers display registered handlers (for debugging)
-h, --help help for roulette -h, --help help for roulette
--images enable support for image files --images enable support for image files
-i, --info expose informational endpoints -i, --info expose informational endpoints
--maximum-files uint skip directories with file counts above this value (default 4294967295) --max-directory-scans uint number of directories to scan at once (default 32)
--minimum-files uint skip directories with file counts below this value (default 1) --max-file-count uint skip directories with file counts above this value (default 4294967295)
--page-length uint32 pagination length for info pages --max-file-scans uint number of files to scan at once (default 256)
-p, --port uint16 port to listen on (default 8080) --min-file-count uint skip directories with file counts below this value (default 1)
--prefix string root path for http handlers (for reverse proxying) (default "/") --page-length uint32 pagination length for info pages
--profile register net/http/pprof handlers -p, --port uint16 port to listen on (default 8080)
-r, --recursive recurse into subdirectories --prefix string root path for http handlers (for reverse proxying) (default "/")
--refresh enable automatic page refresh via query parameter --profile register net/http/pprof handlers
--russian remove selected images after serving -r, --recursive recurse into subdirectories
-s, --sort enable sorting --refresh enable automatic page refresh via query parameter
--text enable support for text files --russian remove selected images after serving
-v, --verbose log accessed files and other information to stdout -s, --sort enable sorting
-V, --version display version and exit --text enable support for text files
--video enable support for video files -v, --verbose log accessed files and other information to stdout
-V, --version display version and exit
--video enable support for video files
``` ```
## Building the Docker container ## Building the Docker container

View File

@ -21,14 +21,6 @@ import (
"seedno.de/seednode/roulette/types" "seedno.de/seednode/roulette/types"
) )
type maxConcurrency int
const (
// avoid hitting default open file descriptor limits (1024)
maxDirectoryScans maxConcurrency = 32
maxFileScans maxConcurrency = 256
)
type regexes struct { type regexes struct {
alphanumeric *regexp.Regexp alphanumeric *regexp.Regexp
filename *regexp.Regexp filename *regexp.Regexp
@ -331,7 +323,7 @@ func walkPath(path string, fileChannel chan<- string, fileScans chan int, stats
errorChannel <- err errorChannel <- err
} }
if files > 0 && (files < int(MinimumFileCount)) || (files > int(MaximumFileCount)) { if files > 0 && (files < int(MinFileCount)) || (files > int(MaxFileCount)) {
// This count will not otherwise include the parent directory itself, so increment by one // This count will not otherwise include the parent directory itself, so increment by one
stats.directoriesSkipped <- directories + 1 stats.directoriesSkipped <- directories + 1
stats.filesSkipped <- files stats.filesSkipped <- files
@ -368,8 +360,8 @@ func scanPaths(paths []string, sort string, cache *fileCache, formats *types.Typ
fileChannel := make(chan string) fileChannel := make(chan string)
errorChannel := make(chan error) errorChannel := make(chan error)
directoryScans := make(chan int, maxDirectoryScans) directoryScans := make(chan int, MaxDirScans)
fileScans := make(chan int, maxFileScans) fileScans := make(chan int, MaxFileScans)
done := make(chan bool, 1) done := make(chan bool, 1)
stats := &scanStats{ stats := &scanStats{

View File

@ -241,7 +241,7 @@ func serveAvailableMimeTypes() httprouter.Handle {
w.Write(response) w.Write(response)
if Verbose { if Verbose {
fmt.Printf("%s | Served available MIME type list (%s) to %s in %s\n", fmt.Printf("%s | Serve: Available MIME type list (%s) to %s in %s\n",
startTime.Format(logDate), startTime.Format(logDate),
humanReadableSize(len(response)), humanReadableSize(len(response)),
realIP(r), realIP(r),
@ -262,7 +262,7 @@ func serveEnabledMimeTypes(formats *types.Types) httprouter.Handle {
w.Write(response) w.Write(response)
if Verbose { if Verbose {
fmt.Printf("%s | Served registered MIME type list (%s) to %s in %s\n", fmt.Printf("%s | Serve: Registered MIME type list (%s) to %s in %s\n",
startTime.Format(logDate), startTime.Format(logDate),
humanReadableSize(len(response)), humanReadableSize(len(response)),
realIP(r), realIP(r),

View File

@ -5,49 +5,63 @@ Copyright © 2023 Seednode <seednode@seedno.de>
package cmd package cmd
import ( import (
"errors"
"log" "log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const ( const (
ReleaseVersion string = "0.92.2" ReleaseVersion string = "0.93.0"
) )
var ( var (
All bool All bool
Audio bool Audio bool
Bind string Bind string
Cache bool Cache bool
CacheFile string CacheFile string
CaseSensitive bool CaseSensitive bool
Code bool Code bool
CodeTheme string CodeTheme string
ExitOnError bool ExitOnError bool
Filtering bool Filtering bool
Flash bool Flash bool
Handlers bool Handlers bool
Images bool Images bool
Info bool Info bool
MaximumFileCount uint MaxDirScans uint
MinimumFileCount uint MaxFileScans uint
PageLength uint32 MaxFileCount uint
Port uint16 MinFileCount uint
Prefix string PageLength uint32
Profile bool Port uint16
Recursive bool Prefix string
Refresh bool Profile bool
Russian bool Recursive bool
Sorting bool Refresh bool
Text bool Russian bool
Verbose bool Sorting bool
Version bool Text bool
Videos bool Verbose bool
Version bool
Videos bool
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: "roulette <path> [path]...", Use: "roulette <path> [path]...",
Short: "Serves random media from the specified directories.", Short: "Serves random media from the specified directories.",
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
if MaxDirScans < 1 {
return errors.New("max directory scan count must be a positive integer")
}
if MaxFileScans < 1 {
return errors.New("max file scan count must be a positive integer")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
err := ServePage(args) err := ServePage(args)
if err != nil { if err != nil {
@ -81,8 +95,10 @@ func init() {
rootCmd.Flags().BoolVar(&Handlers, "handlers", false, "display registered handlers (for debugging)") rootCmd.Flags().BoolVar(&Handlers, "handlers", false, "display registered handlers (for debugging)")
rootCmd.Flags().BoolVar(&Images, "images", false, "enable support for image files") rootCmd.Flags().BoolVar(&Images, "images", false, "enable support for image files")
rootCmd.Flags().BoolVarP(&Info, "info", "i", false, "expose informational endpoints") rootCmd.Flags().BoolVarP(&Info, "info", "i", false, "expose informational endpoints")
rootCmd.Flags().UintVar(&MaximumFileCount, "maximum-files", 1<<32-1, "skip directories with file counts above this value") rootCmd.Flags().UintVar(&MaxDirScans, "max-directory-scans", 32, "number of directories to scan at once")
rootCmd.Flags().UintVar(&MinimumFileCount, "minimum-files", 1, "skip directories with file counts below this value") rootCmd.Flags().UintVar(&MaxFileScans, "max-file-scans", 256, "number of files to scan at once")
rootCmd.Flags().UintVar(&MaxFileCount, "max-file-count", 1<<32-1, "skip directories with file counts above this value")
rootCmd.Flags().UintVar(&MinFileCount, "min-file-count", 1, "skip directories with file counts below this value")
rootCmd.Flags().Uint32Var(&PageLength, "page-length", 0, "pagination length for info pages") rootCmd.Flags().Uint32Var(&PageLength, "page-length", 0, "pagination length for info pages")
rootCmd.Flags().Uint16VarP(&Port, "port", "p", 8080, "port to listen on") rootCmd.Flags().Uint16VarP(&Port, "port", "p", 8080, "port to listen on")
rootCmd.Flags().StringVar(&Prefix, "prefix", "/", "root path for http handlers (for reverse proxying)") rootCmd.Flags().StringVar(&Prefix, "prefix", "/", "root path for http handlers (for reverse proxying)")