diff options
| author | İbrahim Serdar Açıkgöz <serdaracikgoz86@gmail.com> | 2019-01-03 18:30:01 +0300 |
|---|---|---|
| committer | İbrahim Serdar Açıkgöz <serdaracikgoz86@gmail.com> | 2019-01-03 18:30:01 +0300 |
| commit | 4778c038850a98751401b55a042f2d3a0ff94d0b (patch) | |
| tree | c844e03dbcf6ea046e958e901cbd8d681b3c694d | |
| parent | error messages and semaphores added (diff) | |
| download | gitbatch-4778c038850a98751401b55a042f2d3a0ff94d0b.tar.gz | |
async loading
| -rw-r--r-- | pkg/git/util-load.go | 41 | ||||
| -rw-r--r-- | pkg/gui/gui.go | 36 |
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 { |
