Use atomic values instead of mutexes
This commit is contained in:
47
main.go
47
main.go
@@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"cook/processor"
|
"cook/processor"
|
||||||
@@ -18,10 +19,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type GlobalStats struct {
|
type GlobalStats struct {
|
||||||
TotalMatches int
|
TotalMatches int64
|
||||||
TotalModifications int
|
TotalModifications int64
|
||||||
ProcessedFiles int
|
ProcessedFiles int64
|
||||||
FailedFiles int
|
FailedFiles int64
|
||||||
ModificationsPerCommand sync.Map
|
ModificationsPerCommand sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +139,6 @@ func main() {
|
|||||||
|
|
||||||
// Add performance tracking
|
// Add performance tracking
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
var fileMutex sync.Mutex
|
|
||||||
|
|
||||||
// Create a map to store loggers for each command
|
// Create a map to store loggers for each command
|
||||||
commandLoggers := make(map[string]*logger.Logger)
|
commandLoggers := make(map[string]*logger.Logger)
|
||||||
@@ -177,15 +177,17 @@ func main() {
|
|||||||
fileData, err := os.ReadFile(file)
|
fileData, err := os.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to read file %q: %v", file, err)
|
logger.Error("Failed to read file %q: %v", file, err)
|
||||||
|
atomic.AddInt64(&stats.FailedFiles, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileDataStr := string(fileData)
|
fileDataStr := string(fileData)
|
||||||
|
|
||||||
isChanged := false
|
isChanged := false
|
||||||
logger.Debug("Running isolate commands for file %q", file)
|
logger.Debug("Running isolate commands for file %q", file)
|
||||||
fileDataStr, err = RunIsolateCommands(association, file, fileDataStr, &fileMutex)
|
fileDataStr, err = RunIsolateCommands(association, file, fileDataStr)
|
||||||
if err != nil && err != NothingToDo {
|
if err != nil && err != NothingToDo {
|
||||||
logger.Error("Failed to run isolate commands for file %q: %v", file, err)
|
logger.Error("Failed to run isolate commands for file %q: %v", file, err)
|
||||||
|
atomic.AddInt64(&stats.FailedFiles, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != NothingToDo {
|
if err != NothingToDo {
|
||||||
@@ -193,9 +195,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("Running other commands for file %q", file)
|
logger.Debug("Running other commands for file %q", file)
|
||||||
fileDataStr, err = RunOtherCommands(file, fileDataStr, association, &fileMutex, commandLoggers)
|
fileDataStr, err = RunOtherCommands(file, fileDataStr, association, commandLoggers)
|
||||||
if err != nil && err != NothingToDo {
|
if err != nil && err != NothingToDo {
|
||||||
logger.Error("Failed to run other commands for file %q: %v", file, err)
|
logger.Error("Failed to run other commands for file %q: %v", file, err)
|
||||||
|
atomic.AddInt64(&stats.FailedFiles, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != NothingToDo {
|
if err != NothingToDo {
|
||||||
@@ -207,6 +210,7 @@ func main() {
|
|||||||
err = db.SaveFile(file, fileData)
|
err = db.SaveFile(file, fileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to save file %q to database: %v", file, err)
|
logger.Error("Failed to save file %q to database: %v", file, err)
|
||||||
|
atomic.AddInt64(&stats.FailedFiles, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,9 +219,13 @@ func main() {
|
|||||||
err = os.WriteFile(file, []byte(fileDataStr), 0644)
|
err = os.WriteFile(file, []byte(fileDataStr), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to write file %q: %v", file, err)
|
logger.Error("Failed to write file %q: %v", file, err)
|
||||||
|
atomic.AddInt64(&stats.FailedFiles, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only increment ProcessedFiles once per file, after all processing is complete
|
||||||
|
atomic.AddInt64(&stats.ProcessedFiles, 1)
|
||||||
|
|
||||||
logger.Debug("File %q processed in %v", file, time.Since(fileStartTime))
|
logger.Debug("File %q processed in %v", file, time.Since(fileStartTime))
|
||||||
}, file, commands)
|
}, file, commands)
|
||||||
}
|
}
|
||||||
@@ -225,8 +233,9 @@ func main() {
|
|||||||
|
|
||||||
processingTime := time.Since(startTime)
|
processingTime := time.Since(startTime)
|
||||||
logger.Info("Processing completed in %v", processingTime)
|
logger.Info("Processing completed in %v", processingTime)
|
||||||
if stats.ProcessedFiles > 0 {
|
processedFiles := atomic.LoadInt64(&stats.ProcessedFiles)
|
||||||
logger.Info("Average time per file: %v", processingTime/time.Duration(stats.ProcessedFiles))
|
if processedFiles > 0 {
|
||||||
|
logger.Info("Average time per file: %v", processingTime/time.Duration(processedFiles))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Also give each command its own logger, maybe prefix it with something... Maybe give commands a name?
|
// TODO: Also give each command its own logger, maybe prefix it with something... Maybe give commands a name?
|
||||||
@@ -269,11 +278,13 @@ func main() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Print summary
|
// Print summary
|
||||||
if stats.TotalModifications == 0 {
|
totalModifications := atomic.LoadInt64(&stats.TotalModifications)
|
||||||
|
if totalModifications == 0 {
|
||||||
logger.Warning("No modifications were made in any files")
|
logger.Warning("No modifications were made in any files")
|
||||||
} else {
|
} else {
|
||||||
|
failedFiles := atomic.LoadInt64(&stats.FailedFiles)
|
||||||
logger.Info("Operation complete! Modified %d values in %d/%d files",
|
logger.Info("Operation complete! Modified %d values in %d/%d files",
|
||||||
stats.TotalModifications, stats.ProcessedFiles, stats.ProcessedFiles+stats.FailedFiles)
|
totalModifications, processedFiles, processedFiles+failedFiles)
|
||||||
sortedCommands := []string{}
|
sortedCommands := []string{}
|
||||||
stats.ModificationsPerCommand.Range(func(key, value interface{}) bool {
|
stats.ModificationsPerCommand.Range(func(key, value interface{}) bool {
|
||||||
sortedCommands = append(sortedCommands, key.(string))
|
sortedCommands = append(sortedCommands, key.(string))
|
||||||
@@ -358,7 +369,7 @@ func CreateExampleConfig() {
|
|||||||
|
|
||||||
var NothingToDo = errors.New("nothing to do")
|
var NothingToDo = errors.New("nothing to do")
|
||||||
|
|
||||||
func RunOtherCommands(file string, fileDataStr string, association utils.FileCommandAssociation, fileMutex *sync.Mutex, commandLoggers map[string]*logger.Logger) (string, error) {
|
func RunOtherCommands(file string, fileDataStr string, association utils.FileCommandAssociation, commandLoggers map[string]*logger.Logger) (string, error) {
|
||||||
// Aggregate all the modifications and execute them
|
// Aggregate all the modifications and execute them
|
||||||
modifications := []utils.ReplaceCommand{}
|
modifications := []utils.ReplaceCommand{}
|
||||||
for _, command := range association.Commands {
|
for _, command := range association.Commands {
|
||||||
@@ -396,16 +407,13 @@ func RunOtherCommands(file string, fileDataStr string, association utils.FileCom
|
|||||||
var count int
|
var count int
|
||||||
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
||||||
|
|
||||||
fileMutex.Lock()
|
atomic.AddInt64(&stats.TotalModifications, int64(count))
|
||||||
stats.ProcessedFiles++
|
|
||||||
stats.TotalModifications += count
|
|
||||||
fileMutex.Unlock()
|
|
||||||
|
|
||||||
logger.Info("Executed %d modifications for file %q", count, file)
|
logger.Info("Executed %d modifications for file %q", count, file)
|
||||||
return fileDataStr, nil
|
return fileDataStr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunIsolateCommands(association utils.FileCommandAssociation, file string, fileDataStr string, fileMutex *sync.Mutex) (string, error) {
|
func RunIsolateCommands(association utils.FileCommandAssociation, file string, fileDataStr string) (string, error) {
|
||||||
anythingDone := false
|
anythingDone := false
|
||||||
for _, isolateCommand := range association.IsolateCommands {
|
for _, isolateCommand := range association.IsolateCommands {
|
||||||
logger.Info("Processing file %q with isolate command %q", file, isolateCommand.Regex)
|
logger.Info("Processing file %q with isolate command %q", file, isolateCommand.Regex)
|
||||||
@@ -424,10 +432,7 @@ func RunIsolateCommands(association utils.FileCommandAssociation, file string, f
|
|||||||
var count int
|
var count int
|
||||||
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
fileDataStr, count = utils.ExecuteModifications(modifications, fileDataStr)
|
||||||
|
|
||||||
fileMutex.Lock()
|
atomic.AddInt64(&stats.TotalModifications, int64(count))
|
||||||
stats.ProcessedFiles++
|
|
||||||
stats.TotalModifications += count
|
|
||||||
fileMutex.Unlock()
|
|
||||||
|
|
||||||
logger.Info("Executed %d isolate modifications for file %q", count, file)
|
logger.Info("Executed %d isolate modifications for file %q", count, file)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user