mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-01-22 05:29:44 +02:00
Speed up refresh using concurrency and wait groups
Previously our synchronous refreshes took far longer because nothing was happening concurrently. We now run refresh functions concurrently and use a wait group to ensure they're all done before returning
This commit is contained in:
parent
272e021c08
commit
63e5790410
@ -91,59 +91,70 @@ func (self *RefreshHelper) Refresh(options types.RefreshOptions) error {
|
|||||||
scopeSet = set.NewFromSlice(options.Scope)
|
scopeSet = set.NewFromSlice(options.Scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh := func(f func()) {
|
wg := sync.WaitGroup{}
|
||||||
|
refresh := func(name string, f func()) {
|
||||||
if options.Mode == types.ASYNC {
|
if options.Mode == types.ASYNC {
|
||||||
self.c.OnWorker(func(t gocui.Task) {
|
self.c.OnWorker(func(t gocui.Task) {
|
||||||
f()
|
f()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
f()
|
wg.Add(1)
|
||||||
|
go utils.Safe(func() {
|
||||||
|
t := time.Now()
|
||||||
|
defer wg.Done()
|
||||||
|
f()
|
||||||
|
self.c.Log.Infof(fmt.Sprintf("refreshed %s in %s", name, time.Since(t)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.COMMITS) || scopeSet.Includes(types.BRANCHES) || scopeSet.Includes(types.REFLOG) || scopeSet.Includes(types.BISECT_INFO) {
|
if scopeSet.Includes(types.COMMITS) || scopeSet.Includes(types.BRANCHES) || scopeSet.Includes(types.REFLOG) || scopeSet.Includes(types.BISECT_INFO) {
|
||||||
refresh(self.refreshCommits)
|
// whenever we change commits, we should update branches because the upstream/downstream
|
||||||
|
// counts can change. Whenever we change branches we should also change commits
|
||||||
|
// e.g. in the case of switching branches.
|
||||||
|
refresh("commits and commit files", self.refreshCommitsAndCommitFiles)
|
||||||
|
refresh("reflog and branches", self.refreshReflogAndBranches)
|
||||||
} else if scopeSet.Includes(types.REBASE_COMMITS) {
|
} else if scopeSet.Includes(types.REBASE_COMMITS) {
|
||||||
// the above block handles rebase commits so we only need to call this one
|
// the above block handles rebase commits so we only need to call this one
|
||||||
// if we've asked specifically for rebase commits and not those other things
|
// if we've asked specifically for rebase commits and not those other things
|
||||||
refresh(func() { _ = self.refreshRebaseCommits() })
|
refresh("rebase commits", func() { _ = self.refreshRebaseCommits() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.SUB_COMMITS) {
|
if scopeSet.Includes(types.SUB_COMMITS) {
|
||||||
refresh(func() { _ = self.refreshSubCommitsWithLimit() })
|
refresh("sub commits", func() { _ = self.refreshSubCommitsWithLimit() })
|
||||||
}
|
}
|
||||||
|
|
||||||
// reason we're not doing this if the COMMITS type is included is that if the COMMITS type _is_ included we will refresh the commit files context anyway
|
// reason we're not doing this if the COMMITS type is included is that if the COMMITS type _is_ included we will refresh the commit files context anyway
|
||||||
if scopeSet.Includes(types.COMMIT_FILES) && !scopeSet.Includes(types.COMMITS) {
|
if scopeSet.Includes(types.COMMIT_FILES) && !scopeSet.Includes(types.COMMITS) {
|
||||||
refresh(func() { _ = self.refreshCommitFilesContext() })
|
refresh("commit files", func() { _ = self.refreshCommitFilesContext() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.FILES) || scopeSet.Includes(types.SUBMODULES) {
|
if scopeSet.Includes(types.FILES) || scopeSet.Includes(types.SUBMODULES) {
|
||||||
refresh(func() { _ = self.refreshFilesAndSubmodules() })
|
refresh("files", func() { _ = self.refreshFilesAndSubmodules() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.STASH) {
|
if scopeSet.Includes(types.STASH) {
|
||||||
refresh(func() { _ = self.refreshStashEntries() })
|
refresh("stash", func() { _ = self.refreshStashEntries() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.TAGS) {
|
if scopeSet.Includes(types.TAGS) {
|
||||||
refresh(func() { _ = self.refreshTags() })
|
refresh("tags", func() { _ = self.refreshTags() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.REMOTES) {
|
if scopeSet.Includes(types.REMOTES) {
|
||||||
refresh(func() { _ = self.refreshRemotes() })
|
refresh("remotes", func() { _ = self.refreshRemotes() })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.STAGING) {
|
if scopeSet.Includes(types.STAGING) {
|
||||||
refresh(func() { _ = self.stagingHelper.RefreshStagingPanel(types.OnFocusOpts{}) })
|
refresh("staging", func() { _ = self.stagingHelper.RefreshStagingPanel(types.OnFocusOpts{}) })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.PATCH_BUILDING) {
|
if scopeSet.Includes(types.PATCH_BUILDING) {
|
||||||
refresh(func() { _ = self.patchBuildingHelper.RefreshPatchBuildingPanel(types.OnFocusOpts{}) })
|
refresh("patch building", func() { _ = self.patchBuildingHelper.RefreshPatchBuildingPanel(types.OnFocusOpts{}) })
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopeSet.Includes(types.MERGE_CONFLICTS) || scopeSet.Includes(types.FILES) {
|
if scopeSet.Includes(types.MERGE_CONFLICTS) || scopeSet.Includes(types.FILES) {
|
||||||
refresh(func() { _ = self.mergeConflictsHelper.RefreshMergeState() })
|
refresh("merge conflicts", func() { _ = self.mergeConflictsHelper.RefreshMergeState() })
|
||||||
}
|
}
|
||||||
|
|
||||||
self.refreshStatus()
|
self.refreshStatus()
|
||||||
@ -151,6 +162,8 @@ func (self *RefreshHelper) Refresh(options types.RefreshOptions) error {
|
|||||||
if options.Then != nil {
|
if options.Then != nil {
|
||||||
options.Then()
|
options.Then()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Mode == types.BLOCK_UI {
|
if options.Mode == types.BLOCK_UI {
|
||||||
@ -218,41 +231,29 @@ func (self *RefreshHelper) refreshReflogCommitsConsideringStartup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// whenever we change commits, we should update branches because the upstream/downstream
|
func (self *RefreshHelper) refreshReflogAndBranches() {
|
||||||
// counts can change. Whenever we change branches we should probably also change commits
|
self.refreshReflogCommitsConsideringStartup()
|
||||||
// e.g. in the case of switching branches.
|
|
||||||
func (self *RefreshHelper) refreshCommits() {
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
wg.Add(2)
|
|
||||||
|
|
||||||
go utils.Safe(func() {
|
self.refreshBranches()
|
||||||
self.refreshReflogCommitsConsideringStartup()
|
}
|
||||||
|
|
||||||
self.refreshBranches()
|
func (self *RefreshHelper) refreshCommitsAndCommitFiles() {
|
||||||
wg.Done()
|
_ = self.refreshCommitsWithLimit()
|
||||||
})
|
ctx, ok := self.c.Contexts().CommitFiles.GetParentContext()
|
||||||
|
if ok && ctx.GetKey() == context.LOCAL_COMMITS_CONTEXT_KEY {
|
||||||
go utils.Safe(func() {
|
// This makes sense when we've e.g. just amended a commit, meaning we get a new commit SHA at the same position.
|
||||||
_ = self.refreshCommitsWithLimit()
|
// However if we've just added a brand new commit, it pushes the list down by one and so we would end up
|
||||||
ctx, ok := self.c.Contexts().CommitFiles.GetParentContext()
|
// showing the contents of a different commit than the one we initially entered.
|
||||||
if ok && ctx.GetKey() == context.LOCAL_COMMITS_CONTEXT_KEY {
|
// Ideally we would know when to refresh the commit files context and when not to,
|
||||||
// This makes sense when we've e.g. just amended a commit, meaning we get a new commit SHA at the same position.
|
// or perhaps we could just pop that context off the stack whenever cycling windows.
|
||||||
// However if we've just added a brand new commit, it pushes the list down by one and so we would end up
|
// For now the awkwardness remains.
|
||||||
// showing the contents of a different commit than the one we initially entered.
|
commit := self.c.Contexts().LocalCommits.GetSelected()
|
||||||
// Ideally we would know when to refresh the commit files context and when not to,
|
if commit != nil {
|
||||||
// or perhaps we could just pop that context off the stack whenever cycling windows.
|
self.c.Contexts().CommitFiles.SetRef(commit)
|
||||||
// For now the awkwardness remains.
|
self.c.Contexts().CommitFiles.SetTitleRef(commit.RefName())
|
||||||
commit := self.c.Contexts().LocalCommits.GetSelected()
|
_ = self.refreshCommitFilesContext()
|
||||||
if commit != nil {
|
|
||||||
self.c.Contexts().CommitFiles.SetRef(commit)
|
|
||||||
self.c.Contexts().CommitFiles.SetTitleRef(commit.RefName())
|
|
||||||
_ = self.refreshCommitFilesContext()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
wg.Done()
|
}
|
||||||
})
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user