From ce7795361a52f4f80f72f0184f1bd02c16a4380c Mon Sep 17 00:00:00 2001 From: Simon Martens Date: Mon, 11 Nov 2024 22:13:47 +0100 Subject: [PATCH] Intoroduced concurrncy in filereading --- app/kgpz.go | 21 +++++++++++++-------- kgpz_web.go | 10 ++-------- providers/xmlprovider.go | 24 ++++++++++++++++-------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/kgpz.go b/app/kgpz.go index e10dec7..f4a4cb9 100644 --- a/app/kgpz.go +++ b/app/kgpz.go @@ -1,7 +1,6 @@ package app import ( - "fmt" "os" "path/filepath" "sync" @@ -31,11 +30,17 @@ type Library struct { type KGPZ struct { lmu sync.Mutex + gmu sync.Mutex Config *providers.ConfigProvider Repo *providers.GitProvider Library } +func (k *KGPZ) Init() { + go k.initRepo() + k.Serialize() +} + func NewKGPZ(config *providers.ConfigProvider) *KGPZ { if config == nil { panic("ConfigProvider is nil") @@ -55,7 +60,9 @@ func (k *KGPZ) IsDebug() bool { func (k *KGPZ) Pull() { // TODO: what happens if the application quits mid-pull? // We need to make sure to exit gracefully - go func(k *KGPZ) { + go func() { + k.gmu.Lock() + defer k.gmu.Unlock() if k.Repo == nil { return } @@ -72,18 +79,19 @@ func (k *KGPZ) Pull() { // Locking is handled in Serialize() k.Serialize() } - }(k) + }() } -func (k *KGPZ) InitRepo() { +func (k *KGPZ) initRepo() { gp, err := providers.NewGitProvider(k.Config.Config.GitURL, k.Config.Config.FolderPath, k.Config.Config.GitBranch) if err != nil { helpers.LogOnErr(&gp, err, "Error creating GitProvider") return } - fmt.Println("InitRepo") + k.gmu.Lock() k.Repo = gp + k.gmu.Unlock() k.Pull() if k.IsDebug() { @@ -93,9 +101,6 @@ func (k *KGPZ) InitRepo() { // This panics if the data cant be read, and there is no data read func (k *KGPZ) Serialize() { - // TODO: maybe dont panic. - // We need to check the requirements only when starting the server - // We can serve an error page new := Library{} wg := sync.WaitGroup{} diff --git a/kgpz_web.go b/kgpz_web.go index 755f0d9..0dde4bb 100644 --- a/kgpz_web.go +++ b/kgpz_web.go @@ -35,17 +35,12 @@ func main() { } kgpz := app.NewKGPZ(cfg) - Bootstrap(kgpz) + kgpz.Init() server := server.Start(kgpz, cfg) Start(kgpz, server) } -func Bootstrap(k *app.KGPZ) { - k.InitRepo() - k.Serialize() -} - func Start(k *app.KGPZ, s *server.Server) { s.Start() @@ -83,8 +78,7 @@ func Start(k *app.KGPZ, s *server.Server) { fmt.Println("Pulling repo.") k.Pull() } else if input == "q" { - s := os.Signal(syscall.SIGTERM) - sigs <- s + sigs <- os.Signal(syscall.SIGTERM) } } }() diff --git a/providers/xmlprovider.go b/providers/xmlprovider.go index dcfd214..5aee31d 100644 --- a/providers/xmlprovider.go +++ b/providers/xmlprovider.go @@ -20,16 +20,24 @@ type XMLProvider[T KGPZXML[T]] struct { } func (p *XMLProvider[T]) Load() error { + // Introduce goroutine for every path, locking on append: + var wg sync.WaitGroup for _, path := range p.paths { - var data T - if err := UnmarshalFile(path, &data); err != nil { - fmt.Println(err) - return err - } - p.mu.Lock() - p.Items = p.Items.Append(data) - p.mu.Unlock() + wg.Add(1) + go func(path string) { + defer wg.Done() + var data T + if err := UnmarshalFile(path, &data); err != nil { + fmt.Println(err) + return + } + p.mu.Lock() + defer p.mu.Unlock() + p.Items = p.Items.Append(data) + }(path) } + wg.Wait() + return nil }