From 0ac39a7ab5db077fcf0df827e32bf6e625e980da Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sat, 19 Nov 2022 11:33:12 +0100 Subject: WIP --- cache/repo_cache_common.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'cache/repo_cache_common.go') diff --git a/cache/repo_cache_common.go b/cache/repo_cache_common.go index 43ac6beb..18ba52f3 100644 --- a/cache/repo_cache_common.go +++ b/cache/repo_cache_common.go @@ -126,9 +126,13 @@ func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult { continue } + // TODO: have subcache do the merging? switch result.Status { - case entity.MergeStatusNew, entity.MergeStatusUpdated: + case entity.MergeStatusNew: b := result.Entity.(*bug.Bug) + _, err := c.bugs.add(b) + case entity.MergeStatusUpdated: + _, err := c.bugs.entityUpdated(b) snap := b.Compile() c.muBug.Lock() c.bugExcerpts[result.Id] = NewBugExcerpt(b, snap) -- cgit From f2def3a9331080a02e57710a859d2aac608ed44c Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Mon, 19 Dec 2022 18:09:59 +0100 Subject: WIP --- cache/repo_cache_common.go | 64 ++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'cache/repo_cache_common.go') diff --git a/cache/repo_cache_common.go b/cache/repo_cache_common.go index 18ba52f3..1aed04b2 100644 --- a/cache/repo_cache_common.go +++ b/cache/repo_cache_common.go @@ -1,8 +1,6 @@ package cache import ( - "fmt" - "github.com/go-git/go-billy/v5" "github.com/pkg/errors" @@ -186,64 +184,64 @@ func (c *RepoCache) Pull(remote string) error { } func (c *RepoCache) SetUserIdentity(i *IdentityCache) error { - err := identity.SetUserIdentity(c.repo, i.Identity) - if err != nil { - return err - } - - c.muIdentity.RLock() - defer c.muIdentity.RUnlock() + c.muUserIdentity.RLock() + defer c.muUserIdentity.RUnlock() // Make sure that everything is fine - if _, ok := c.identities[i.Id()]; !ok { + if _, err := c.identities.Resolve(i.Id()); err != nil { panic("SetUserIdentity while the identity is not from the cache, something is wrong") } + err := identity.SetUserIdentity(c.repo, i.Identity) + if err != nil { + return err + } + c.userIdentityId = i.Id() return nil } func (c *RepoCache) GetUserIdentity() (*IdentityCache, error) { + c.muUserIdentity.RLock() if c.userIdentityId != "" { - i, ok := c.identities[c.userIdentityId] - if ok { - return i, nil - } + defer c.muUserIdentity.RUnlock() + return c.identities.Resolve(c.userIdentityId) } + c.muUserIdentity.RUnlock() - c.muIdentity.Lock() - defer c.muIdentity.Unlock() + c.muUserIdentity.Lock() + defer c.muUserIdentity.Unlock() - i, err := identity.GetUserIdentity(c.repo) + i, err := identity.GetUserIdentityId(c.repo) if err != nil { return nil, err } - cached := NewIdentityCache(c, i) - c.identities[i.Id()] = cached - c.userIdentityId = i.Id() + c.userIdentityId = i - return cached, nil + return c.identities.Resolve(i) } func (c *RepoCache) GetUserIdentityExcerpt() (*IdentityExcerpt, error) { - if c.userIdentityId == "" { - id, err := identity.GetUserIdentityId(c.repo) - if err != nil { - return nil, err - } - c.userIdentityId = id + c.muUserIdentity.RLock() + if c.userIdentityId != "" { + defer c.muUserIdentity.RUnlock() + return c.identities.ResolveExcerpt(c.userIdentityId) } + c.muUserIdentity.RUnlock() - c.muIdentity.RLock() - defer c.muIdentity.RUnlock() + c.muUserIdentity.Lock() + defer c.muUserIdentity.Unlock() - excerpt, ok := c.identitiesExcerpts[c.userIdentityId] - if !ok { - return nil, fmt.Errorf("cache: missing identity excerpt %v", c.userIdentityId) + i, err := identity.GetUserIdentityId(c.repo) + if err != nil { + return nil, err } - return excerpt, nil + + c.userIdentityId = i + + return c.identities.ResolveExcerpt(i) } func (c *RepoCache) IsUserIdentitySet() (bool, error) { -- cgit From 9b98fc06489353053564b431ac0c0d73a5c55a56 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Wed, 21 Dec 2022 21:54:36 +0100 Subject: cache: tie up the refactor up to compiling --- cache/repo_cache_common.go | 97 ++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 68 deletions(-) (limited to 'cache/repo_cache_common.go') diff --git a/cache/repo_cache_common.go b/cache/repo_cache_common.go index 1aed04b2..f768b8e2 100644 --- a/cache/repo_cache_common.go +++ b/cache/repo_cache_common.go @@ -1,10 +1,11 @@ package cache import ( + "sync" + "github.com/go-git/go-billy/v5" "github.com/pkg/errors" - "github.com/MichaelMure/git-bug/entities/bug" "github.com/MichaelMure/git-bug/entities/identity" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/repository" @@ -72,76 +73,40 @@ func (c *RepoCache) StoreData(data []byte) (repository.Hash, error) { // Fetch retrieve updates from a remote // This does not change the local bugs or identities state func (c *RepoCache) Fetch(remote string) (string, error) { - stdout1, err := identity.Fetch(c.repo, remote) - if err != nil { - return stdout1, err - } - - stdout2, err := bug.Fetch(c.repo, remote) - if err != nil { - return stdout2, err + prefixes := make([]string, len(c.subcaches)) + for i, subcache := range c.subcaches { + prefixes[i] = subcache.GetNamespace() } - return stdout1 + stdout2, nil + // fetch everything at once, to have a single auth step if required. + return c.repo.FetchRefs(remote, prefixes...) } // MergeAll will merge all the available remote bug and identities func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult { out := make(chan entity.MergeResult) - // Intercept merge results to update the cache properly + dependency := [][]cacheMgmt{ + {c.identities}, + {c.bugs}, + } + + // run MergeAll according to entities dependencies and merge the results go func() { defer close(out) - author, err := c.GetUserIdentity() - if err != nil { - out <- entity.NewMergeError(err, "") - return - } - - results := identity.MergeAll(c.repo, remote) - for result := range results { - out <- result - - if result.Err != nil { - continue - } - - switch result.Status { - case entity.MergeStatusNew, entity.MergeStatusUpdated: - i := result.Entity.(*identity.Identity) - c.muIdentity.Lock() - c.identitiesExcerpts[result.Id] = NewIdentityExcerpt(i) - c.muIdentity.Unlock() + for _, subcaches := range dependency { + var wg sync.WaitGroup + for _, subcache := range subcaches { + wg.Add(1) + go func(subcache cacheMgmt) { + for res := range subcache.MergeAll(remote) { + out <- res + } + wg.Done() + }(subcache) } - } - - results = bug.MergeAll(c.repo, c.resolvers, remote, author) - for result := range results { - out <- result - - if result.Err != nil { - continue - } - - // TODO: have subcache do the merging? - switch result.Status { - case entity.MergeStatusNew: - b := result.Entity.(*bug.Bug) - _, err := c.bugs.add(b) - case entity.MergeStatusUpdated: - _, err := c.bugs.entityUpdated(b) - snap := b.Compile() - c.muBug.Lock() - c.bugExcerpts[result.Id] = NewBugExcerpt(b, snap) - c.muBug.Unlock() - } - } - - err = c.write() - if err != nil { - out <- entity.NewMergeError(err, "") - return + wg.Wait() } }() @@ -150,17 +115,13 @@ func (c *RepoCache) MergeAll(remote string) <-chan entity.MergeResult { // Push update a remote with the local changes func (c *RepoCache) Push(remote string) (string, error) { - stdout1, err := identity.Push(c.repo, remote) - if err != nil { - return stdout1, err - } - - stdout2, err := bug.Push(c.repo, remote) - if err != nil { - return stdout2, err + prefixes := make([]string, len(c.subcaches)) + for i, subcache := range c.subcaches { + prefixes[i] = subcache.GetNamespace() } - return stdout1 + stdout2, nil + // push everything at once, to have a single auth step if required + return c.repo.PushRefs(remote, prefixes...) } // Pull will do a Fetch + MergeAll -- cgit