properly propagate context

This commit is contained in:
Massaki Archambault 2024-12-29 22:23:04 -05:00
parent 271e63c960
commit 4c27890404
14 changed files with 59 additions and 50 deletions

View File

@ -1,6 +1,7 @@
package gitea
import (
"context"
"fmt"
"log/slog"
"sync"
@ -58,12 +59,12 @@ func NewClient(logger *slog.Logger, config config.GiteaClientConfig) (*giteaClie
return giteaClient, nil
}
func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) {
func (c *giteaClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) {
if c.rootContent == nil {
rootContent := make(map[string]fstree.GroupSource)
for _, orgName := range c.GiteaClientConfig.OrgNames {
org, err := c.fetchOrganization(orgName)
org, err := c.fetchOrganization(ctx, orgName)
if err != nil {
c.logger.Warn(err.Error())
} else {
@ -72,7 +73,7 @@ func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, er
}
for _, userName := range c.GiteaClientConfig.UserNames {
user, err := c.fetchUser(userName)
user, err := c.fetchUser(ctx, userName)
if err != nil {
c.logger.Warn(err.Error())
} else {
@ -85,12 +86,12 @@ func (c *giteaClient) FetchRootGroupContent() (map[string]fstree.GroupSource, er
return c.rootContent, nil
}
func (c *giteaClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *giteaClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
if org, found := c.organizationCache[int64(gid)]; found {
return c.fetchOrganizationContent(org)
return c.fetchOrganizationContent(ctx, org)
}
if user, found := c.userCache[int64(gid)]; found {
return c.fetchUserContent(user)
return c.fetchUserContent(ctx, user)
}
return nil, nil, fmt.Errorf("invalid gid: %v", gid)
}

View File

@ -1,6 +1,7 @@
package gitea
import (
"context"
"fmt"
"sync"
@ -30,7 +31,7 @@ func (o *Organization) InvalidateContentCache() {
o.childRepositories = nil
}
func (c *giteaClient) fetchOrganization(orgName string) (*Organization, error) {
func (c *giteaClient) fetchOrganization(ctx context.Context, orgName string) (*Organization, error) {
c.organizationCacheMux.RLock()
cachedId, found := c.organizationNameToIDMap[orgName]
if found {
@ -67,7 +68,7 @@ func (c *giteaClient) fetchOrganization(orgName string) (*Organization, error) {
return &newOrg, nil
}
func (c *giteaClient) fetchOrganizationContent(org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *giteaClient) fetchOrganizationContent(ctx context.Context, org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
org.mux.Lock()
defer org.mux.Unlock()
@ -86,7 +87,7 @@ func (c *giteaClient) fetchOrganizationContent(org *Organization) (map[string]fs
return nil, nil, fmt.Errorf("failed to fetch repository in gitea: %v", err)
}
for _, giteaRepository := range giteaRepositories {
repository := c.newRepositoryFromGiteaRepository(giteaRepository)
repository := c.newRepositoryFromGiteaRepository(ctx, giteaRepository)
if repository != nil {
childRepositories[repository.Path] = repository
}

View File

@ -1,6 +1,7 @@
package gitea
import (
"context"
"path"
"code.gitea.io/sdk/gitea"
@ -26,7 +27,7 @@ func (r *Repository) GetDefaultBranch() string {
return r.DefaultBranch
}
func (c *giteaClient) newRepositoryFromGiteaRepository(repository *gitea.Repository) *Repository {
func (c *giteaClient) newRepositoryFromGiteaRepository(ctx context.Context, repository *gitea.Repository) *Repository {
if c.ArchivedRepoHandling == config.ArchivedProjectIgnore && repository.Archived {
return nil
}

View File

@ -1,6 +1,7 @@
package gitea
import (
"context"
"fmt"
"sync"
@ -30,7 +31,7 @@ func (u *User) InvalidateContentCache() {
u.childRepositories = nil
}
func (c *giteaClient) fetchUser(userName string) (*User, error) {
func (c *giteaClient) fetchUser(ctx context.Context, userName string) (*User, error) {
c.userCacheMux.RLock()
cachedId, found := c.userNameToIDMap[userName]
if found {
@ -67,7 +68,7 @@ func (c *giteaClient) fetchUser(userName string) (*User, error) {
return &newUser, nil
}
func (c *giteaClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *giteaClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
user.mux.Lock()
defer user.mux.Unlock()
@ -86,7 +87,7 @@ func (c *giteaClient) fetchUserContent(user *User) (map[string]fstree.GroupSourc
return nil, nil, fmt.Errorf("failed to fetch repository in gitea: %v", err)
}
for _, giteaRepository := range giteaRepositories {
repository := c.newRepositoryFromGiteaRepository(giteaRepository)
repository := c.newRepositoryFromGiteaRepository(ctx, giteaRepository)
if repository != nil {
childRepositories[repository.Path] = repository
}

View File

@ -59,12 +59,12 @@ func NewClient(logger *slog.Logger, config config.GithubClientConfig) (*githubCl
return gitHubClient, nil
}
func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) {
func (c *githubClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) {
if c.rootContent == nil {
rootContent := make(map[string]fstree.GroupSource)
for _, orgName := range c.GithubClientConfig.OrgNames {
org, err := c.fetchOrganization(orgName)
org, err := c.fetchOrganization(ctx, orgName)
if err != nil {
c.logger.Warn(err.Error())
} else {
@ -73,7 +73,7 @@ func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e
}
for _, userName := range c.GithubClientConfig.UserNames {
user, err := c.fetchUser(userName)
user, err := c.fetchUser(ctx, userName)
if err != nil {
c.logger.Warn(err.Error())
} else {
@ -86,12 +86,12 @@ func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e
return c.rootContent, nil
}
func (c *githubClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *githubClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
if org, found := c.organizationCache[int64(gid)]; found {
return c.fetchOrganizationContent(org)
return c.fetchOrganizationContent(ctx, org)
}
if user, found := c.userCache[int64(gid)]; found {
return c.fetchUserContent(user)
return c.fetchUserContent(ctx, user)
}
return nil, nil, fmt.Errorf("invalid gid: %v", gid)
}

View File

@ -31,7 +31,7 @@ func (o *Organization) InvalidateContentCache() {
o.childRepositories = nil
}
func (c *githubClient) fetchOrganization(orgName string) (*Organization, error) {
func (c *githubClient) fetchOrganization(ctx context.Context, orgName string) (*Organization, error) {
c.organizationCacheMux.RLock()
cachedId, found := c.organizationNameToIDMap[orgName]
if found {
@ -48,7 +48,7 @@ func (c *githubClient) fetchOrganization(orgName string) (*Organization, error)
}
// If not found in cache, fetch organization infos from API
githubOrg, _, err := c.client.Organizations.Get(context.Background(), orgName)
githubOrg, _, err := c.client.Organizations.Get(ctx, orgName)
if err != nil {
return nil, fmt.Errorf("failed to fetch organization with name %v: %v", orgName, err)
}
@ -68,7 +68,7 @@ func (c *githubClient) fetchOrganization(orgName string) (*Organization, error)
return &newOrg, nil
}
func (c *githubClient) fetchOrganizationContent(org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *githubClient) fetchOrganizationContent(ctx context.Context, org *Organization) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
org.mux.Lock()
defer org.mux.Unlock()
@ -82,12 +82,12 @@ func (c *githubClient) fetchOrganizationContent(org *Organization) (map[string]f
ListOptions: github.ListOptions{PerPage: 100},
}
for {
githubRepositories, response, err := c.client.Repositories.ListByOrg(context.Background(), org.Name, repositoryListOpt)
githubRepositories, response, err := c.client.Repositories.ListByOrg(ctx, org.Name, repositoryListOpt)
if err != nil {
return nil, nil, fmt.Errorf("failed to fetch repository in github: %v", err)
}
for _, githubRepository := range githubRepositories {
repository := c.newRepositoryFromGithubRepository(githubRepository)
repository := c.newRepositoryFromGithubRepository(ctx, githubRepository)
if repository != nil {
childRepositories[repository.Path] = repository
}

View File

@ -1,6 +1,7 @@
package github
import (
"context"
"path"
"github.com/badjware/gitforgefs/config"
@ -26,7 +27,7 @@ func (r *Repository) GetDefaultBranch() string {
return r.DefaultBranch
}
func (c *githubClient) newRepositoryFromGithubRepository(repository *github.Repository) *Repository {
func (c *githubClient) newRepositoryFromGithubRepository(ctx context.Context, repository *github.Repository) *Repository {
if c.ArchivedRepoHandling == config.ArchivedProjectIgnore && *repository.Archived {
return nil
}

View File

@ -31,7 +31,7 @@ func (u *User) InvalidateContentCache() {
u.childRepositories = nil
}
func (c *githubClient) fetchUser(userName string) (*User, error) {
func (c *githubClient) fetchUser(ctx context.Context, userName string) (*User, error) {
c.userCacheMux.RLock()
cachedId, found := c.userNameToIDMap[userName]
if found {
@ -48,7 +48,7 @@ func (c *githubClient) fetchUser(userName string) (*User, error) {
}
// If not found in cache, fetch user infos from API
githubUser, _, err := c.client.Users.Get(context.Background(), userName)
githubUser, _, err := c.client.Users.Get(ctx, userName)
if err != nil {
return nil, fmt.Errorf("failed to fetch user with name %v: %v", userName, err)
}
@ -68,7 +68,7 @@ func (c *githubClient) fetchUser(userName string) (*User, error) {
return &newUser, nil
}
func (c *githubClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *githubClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
user.mux.Lock()
defer user.mux.Unlock()
@ -82,12 +82,12 @@ func (c *githubClient) fetchUserContent(user *User) (map[string]fstree.GroupSour
ListOptions: github.ListOptions{PerPage: 100},
}
for {
githubRepositories, response, err := c.client.Repositories.ListByUser(context.Background(), user.Name, repositoryListOpt)
githubRepositories, response, err := c.client.Repositories.ListByUser(ctx, user.Name, repositoryListOpt)
if err != nil {
return nil, nil, fmt.Errorf("failed to fetch repository in github: %v", err)
}
for _, githubRepository := range githubRepositories {
repository := c.newRepositoryFromGithubRepository(githubRepository)
repository := c.newRepositoryFromGithubRepository(ctx, githubRepository)
if repository != nil {
childRepositories[repository.Path] = repository
}

View File

@ -1,6 +1,7 @@
package gitlab
import (
"context"
"fmt"
"log/slog"
"slices"
@ -72,14 +73,14 @@ func NewClient(logger *slog.Logger, config config.GitlabClientConfig) (*gitlabCl
return gitlabClient, nil
}
func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) {
func (c *gitlabClient) FetchRootGroupContent(ctx context.Context) (map[string]fstree.GroupSource, error) {
// use cached values if available
if c.rootContent == nil {
rootGroupCache := make(map[string]fstree.GroupSource)
// fetch root groups
for _, gid := range c.GroupIDs {
group, err := c.fetchGroup(gid)
group, err := c.fetchGroup(ctx, gid)
if err != nil {
return nil, err
}
@ -87,7 +88,7 @@ func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e
}
// fetch users
for _, uid := range c.userIDs {
user, err := c.fetchUser(uid)
user, err := c.fetchUser(ctx, uid)
if err != nil {
return nil, err
}
@ -99,20 +100,20 @@ func (c *gitlabClient) FetchRootGroupContent() (map[string]fstree.GroupSource, e
return c.rootContent, nil
}
func (c *gitlabClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *gitlabClient) FetchGroupContent(ctx context.Context, gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
if slices.Contains[[]int, int](c.userIDs, int(gid)) {
// gid is a user
user, err := c.fetchUser(int(gid))
user, err := c.fetchUser(ctx, int(gid))
if err != nil {
return nil, nil, err
}
return c.fetchUserContent(user)
return c.fetchUserContent(ctx, user)
} else {
// gid is a group
group, err := c.fetchGroup(int(gid))
group, err := c.fetchGroup(ctx, int(gid))
if err != nil {
return nil, nil, err
}
return c.fetchGroupContent(group)
return c.fetchGroupContent(ctx, group)
}
}

View File

@ -1,6 +1,7 @@
package gitlab
import (
"context"
"fmt"
"sync"
@ -42,7 +43,7 @@ func (g *Group) InvalidateContentCache() {
g.childGroups = nil
}
func (c *gitlabClient) fetchGroup(gid int) (*Group, error) {
func (c *gitlabClient) fetchGroup(ctx context.Context, gid int) (*Group, error) {
// start by searching the cache
// TODO: cache invalidation?
c.groupCacheMux.RLock()
@ -113,7 +114,7 @@ func (c *gitlabClient) newGroupFromGitlabGroup(gitlabGroup *gitlab.Group) (*Grou
return &newGroup, nil
}
func (c *gitlabClient) fetchGroupContent(group *Group) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *gitlabClient) fetchGroupContent(ctx context.Context, group *Group) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
// Only a single routine can fetch the group content at the time.
// We lock for the whole duration of the function to avoid fetching the same data from the API
// multiple times if concurrent calls where to occur.
@ -162,7 +163,7 @@ func (c *gitlabClient) fetchGroupContent(group *Group) (map[string]fstree.GroupS
return nil, nil, fmt.Errorf("failed to fetch projects in gitlab: %v", err)
}
for _, gitlabProject := range gitlabProjects {
project := c.newProjectFromGitlabProject(gitlabProject)
project := c.newProjectFromGitlabProject(ctx, gitlabProject)
if project != nil {
childProjects[project.Path] = project
}

View File

@ -1,6 +1,7 @@
package gitlab
import (
"context"
"path"
"github.com/badjware/gitforgefs/config"
@ -26,7 +27,7 @@ func (p *Project) GetDefaultBranch() string {
return p.DefaultBranch
}
func (c *gitlabClient) newProjectFromGitlabProject(project *gitlab.Project) *Project {
func (c *gitlabClient) newProjectFromGitlabProject(ctx context.Context, project *gitlab.Project) *Project {
// https://godoc.org/github.com/xanzy/go-gitlab#Project
if c.ArchivedProjectHandling == config.ArchivedProjectIgnore && project.Archived {
return nil

View File

@ -1,6 +1,7 @@
package gitlab
import (
"context"
"fmt"
"sync"
@ -30,7 +31,7 @@ func (u *User) InvalidateContentCache() {
u.childProjects = nil
}
func (c *gitlabClient) fetchUser(uid int) (*User, error) {
func (c *gitlabClient) fetchUser(ctx context.Context, uid int) (*User, error) {
// start by searching the cache
// TODO: cache invalidation?
c.userCacheMux.RLock()
@ -64,7 +65,7 @@ func (c *gitlabClient) fetchUser(uid int) (*User, error) {
return &newUser, nil
}
func (c *gitlabClient) fetchUserContent(user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
func (c *gitlabClient) fetchUserContent(ctx context.Context, user *User) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
// Only a single routine can fetch the user content at the time.
// We lock for the whole duration of the function to avoid fetching the same data from the API
// multiple times if concurrent calls where to occur.
@ -88,7 +89,7 @@ func (c *gitlabClient) fetchUserContent(user *User) (map[string]fstree.GroupSour
return nil, nil, fmt.Errorf("failed to fetch projects in gitlab: %v", err)
}
for _, gitlabProject := range gitlabProjects {
project := c.newProjectFromGitlabProject(gitlabProject)
project := c.newProjectFromGitlabProject(ctx, gitlabProject)
if project != nil {
childProjects[project.Path] = project
}

View File

@ -43,7 +43,7 @@ func newGroupNodeFromSource(ctx context.Context, source GroupSource, param *FSPa
}
func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID())
groups, repositories, err := n.param.GitForge.FetchGroupContent(ctx, n.source.GetGroupID())
if err != nil {
n.param.logger.Error(err.Error())
}
@ -74,7 +74,7 @@ func (n *groupNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
}
func (n *groupNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
groups, repositories, err := n.param.GitForge.FetchGroupContent(n.source.GetGroupID())
groups, repositories, err := n.param.GitForge.FetchGroupContent(ctx, n.source.GetGroupID())
if err != nil {
n.param.logger.Error(err.Error())
} else {

View File

@ -23,8 +23,8 @@ type GitClient interface {
}
type GitForge interface {
FetchRootGroupContent() (map[string]GroupSource, error)
FetchGroupContent(gid uint64) (map[string]GroupSource, map[string]RepositorySource, error)
FetchRootGroupContent(ctx context.Context) (map[string]GroupSource, error)
FetchGroupContent(ctx context.Context, gid uint64) (map[string]GroupSource, map[string]RepositorySource, error)
}
type FSParam struct {
@ -71,7 +71,7 @@ func Start(logger *slog.Logger, mountpoint string, mountoptions []string, param
}
func (n *rootNode) OnAdd(ctx context.Context) {
rootGroups, err := n.param.GitForge.FetchRootGroupContent()
rootGroups, err := n.param.GitForge.FetchRootGroupContent(ctx)
if err != nil {
panic(err)
}