summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/git/util-load.go41
-rw-r--r--pkg/gui/gui.go36
2 files changed, 58 insertions, 19 deletions
diff --git a/pkg/git/util-load.go b/pkg/git/util-load.go
index bf19de8..091716a 100644
--- a/pkg/git/util-load.go
+++ b/pkg/git/util-load.go
@@ -3,10 +3,16 @@ package git
import (
log "github.com/sirupsen/logrus"
+ "context"
"errors"
+ "runtime"
"sync"
+
+ "golang.org/x/sync/semaphore"
)
+type AsyncAdd func(e *RepoEntity)
+
// LoadRepositoryEntities initializes the go-git's repository obejcts with given
// slice of paths. since this job is done parallel, the order of the directories
// is not kept
@@ -46,3 +52,38 @@ func LoadRepositoryEntities(directories []string) (entities []*RepoEntity, err e
}
return entities, nil
}
+
+func LoadRepositoryEntitiesAsync(directories []string, add AsyncAdd) error {
+ ctx := context.TODO()
+
+ var (
+ maxWorkers = runtime.GOMAXPROCS(0)
+ sem = semaphore.NewWeighted(int64(maxWorkers))
+ )
+
+ var mx sync.Mutex
+ for _, dir := range directories {
+ if err := sem.Acquire(ctx, 1); err != nil {
+ log.Errorf("Failed to acquire semaphore: %v", err)
+ break
+ }
+
+ go func(d string) {
+
+ defer sem.Release(1)
+ entity, err := InitializeRepo(d)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "directory": d,
+ }).Trace("Cannot load git repository.")
+ return
+ }
+ // lock so we don't get a race if multiple go routines try to add
+ // to the same entities
+ mx.Lock()
+ add(entity)
+ mx.Unlock()
+ }(dir)
+ }
+ return nil
+}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 6d5de19..120054f 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -113,15 +113,6 @@ func (gui *Gui) Run() error {
g.InputEsc = true
g.SetManagerFunc(gui.layout)
- gui.g = g
- g.Highlight = true
- g.SelFgColor = gocui.ColorGreen
-
- // If InputEsc is true, when ESC sequence is in the buffer and it doesn't
- // match any known sequence, ESC means KeyEsc.
- g.InputEsc = true
- g.SetManagerFunc(gui.layout)
-
// start an async view apart from this loop to show loading screen
go func(g_ui *Gui) {
maxX, maxY := g.Size()
@@ -138,17 +129,18 @@ func (gui *Gui) Run() error {
log.Warn("Loading view cannot be focused.")
return
}
- rs, err := git.LoadRepositoryEntities(g_ui.State.Directories)
- if err != nil {
- g.Close()
- log.Fatal(err)
- return
- }
- g_ui.State.Repositories = rs
+ go git.LoadRepositoryEntitiesAsync(g_ui.State.Directories, gui.addRepository)
+ // rs, err := git.LoadRepositoryEntities(g_ui.State.Directories)
+ // if err != nil {
+ // g.Close()
+ // log.Fatal(err)
+ // return
+ // }
+ // g_ui.State.Repositories = rs
// add gui's repositoryUpdated func as an observer to repositories
- for _, repo := range rs {
- repo.On(git.RepositoryUpdated, gui.repositoryUpdated)
- }
+ // for _, repo := range rs {
+ // repo.On(git.RepositoryUpdated, gui.repositoryUpdated)
+ // }
gui.fillMain(g)
}(gui)
@@ -167,6 +159,12 @@ func (gui *Gui) Run() error {
return nil
}
+func (gui *Gui) addRepository(e *git.RepoEntity) {
+ gui.State.Repositories = append(gui.State.Repositories, e)
+ e.On(git.RepositoryUpdated, gui.repositoryUpdated)
+ e.Refresh()
+}
+
// set the layout and create views with their default size, name etc. values
// TODO: window sizes can be handled better
func (gui *Gui) layout(g *gocui.Gui) error {