Skip to content

Commit

Permalink
revert dial and call all (#1267)
Browse files Browse the repository at this point in the history
  • Loading branch information
ale8k authored Jul 16, 2024
1 parent cb8e097 commit 5d49557
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 73 deletions.
39 changes: 13 additions & 26 deletions internal/jimm/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"database/sql"
"encoding/json"
"fmt"
"sync"

"github.com/juju/juju/api/base"
"github.com/juju/juju/api/controller/controller"
Expand Down Expand Up @@ -45,43 +46,29 @@ var (
// access to.
func (j *JIMM) AllModels(ctx context.Context, user *openfga.User) (jujuparams.UserModelList, error) {
const op = errors.Op("jimm.AllModels")

userModelList := jujuparams.UserModelList{}
var resultMut sync.Mutex
flattenedUml := jujuparams.UserModelList{}

uuidToPerms, err := j.getControllersWithModelPermissionsForUser(ctx, user)
if err != nil {
return userModelList, errors.E(op, err)
return flattenedUml, errors.E(op, err)
}

umlCh := make(chan jujuparams.UserModelList)
errorsCh := make(chan error)

dialAndCallControllers(j.dial, uuidToPerms, errorsCh, func(api API) {
err = j.forEachController(ctx, uuidToPerms.GetControllers(), func(c *dbmodel.Controller, api API) error {
resultMut.Lock()
defer resultMut.Unlock()
uml, err := api.AllModels(ctx)
if err != nil {
errorsCh <- err
return
return err
}
umlCh <- uml
flattenedUml.UserModels = append(flattenedUml.UserModels, uml.UserModels...)
return nil
})

errs := []error{}

for range uuidToPerms {
select {
case uml := <-umlCh:
userModelList.UserModels = append(userModelList.UserModels, uml.UserModels...)
case err := <-errorsCh:
errs = append(errs, err)
}
}

if len(errs) > 0 {
// What do we do with call errors? Just take the first?
return userModelList, errors.E(op, errs[0])
if err != nil {
return flattenedUml, errors.E(err, op)
}

return userModelList, nil
return flattenedUml, nil
}

// AddController adds the specified controller to JIMM. Only
Expand Down
33 changes: 8 additions & 25 deletions internal/jimm/jimm.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ type controllerWithModelPermissions struct {

type controllerPermSet map[string]controllerWithModelPermissions

func (c controllerPermSet) GetControllers() []dbmodel.Controller {
controllers := []dbmodel.Controller{}
for _, v := range c {
controllers = append(controllers, v.controller)
}
return controllers
}

type dialerFunc func(ctx context.Context, ctl *dbmodel.Controller, modelTag names.ModelTag, permissons ...permission) (API, error)

// getControllersWithModelPermissionsForUser returns a map of controller uuids to:
Expand Down Expand Up @@ -242,31 +250,6 @@ func (j *JIMM) getControllersWithModelPermissionsForUser(ctx context.Context, us
return uuidToPerms, nil
}

// dialAndCallControllers dials multiple controllers in their own routines
// from the controller permission set and reports errors on dial to an error channel.
//
// It takes a function which will pass the dialed controller to the function.
// Should you wish to handle concurrency waiting, please read from a channel
// outside the op or create a wait group within the op.
func dialAndCallControllers(
dialerFunc dialerFunc,
p controllerPermSet,
errCh chan error,
op func(api API),
) {
for _, perms := range p {
go func(c controllerWithModelPermissions) {
api, err := dialerFunc(context.Background(), &c.controller, names.ModelTag{}, c.permissions...)
if err != nil {
errCh <- err
return
}
defer api.Close()
op(api)
}(perms)
}
}

// dial dials the controller and model specified by the given Controller
// and ModelTag. If no Dialer has been configured then an error with a
// code of CodeConnectionFailed will be returned.
Expand Down
32 changes: 10 additions & 22 deletions internal/jimm/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"slices"
"sort"
"strings"
"sync"
"time"

jujupermission "github.com/juju/juju/core/permission"
Expand Down Expand Up @@ -764,41 +765,28 @@ func (j *JIMM) ModelStatus(ctx context.Context, user *openfga.User, mt names.Mod
func (j *JIMM) GetAllModelSummariesForUser(ctx context.Context, user *openfga.User) (jujuparams.ModelSummaryResults, error) {
const op = errors.Op("jimm.GetAllModelSummariesForUser")

var resultMut sync.Mutex
flattenedSummaries := jujuparams.ModelSummaryResults{}

uuidToPerms, err := j.getControllersWithModelPermissionsForUser(ctx, user)
if err != nil {
return flattenedSummaries, errors.E(op, err)
}

summariesCh := make(chan jujuparams.ModelSummaryResults)
errorsCh := make(chan error)

dialAndCallControllers(j.dial, uuidToPerms, errorsCh, func(api API) {
err = j.forEachController(ctx, uuidToPerms.GetControllers(), func(c *dbmodel.Controller, api API) error {
resultMut.Lock()
defer resultMut.Unlock()
var out jujuparams.ModelSummaryResults
in := jujuparams.ModelSummariesRequest{UserTag: names.NewUserTag(user.Name).String(), All: true}

if err := api.ListModelSummaries(context.Background(), &in, &out); err != nil {
errorsCh <- err
return
return err
}
summariesCh <- out
flattenedSummaries.Results = append(flattenedSummaries.Results, out.Results...)
return nil
})

errs := []error{}

for range uuidToPerms {
select {
case sum := <-summariesCh:
flattenedSummaries.Results = append(flattenedSummaries.Results, sum.Results...)
case err := <-errorsCh:
errs = append(errs, err)
}
}

if len(errs) > 0 {
// What do we do with call errors? Just take the first?
return flattenedSummaries, errors.E(op, errs[0])
if err != nil {
return flattenedSummaries, errors.E(err, op)
}

// Flatten permissions into single slice for index searching
Expand Down

0 comments on commit 5d49557

Please sign in to comment.