Skip to content

Commit

Permalink
Handle the relation changes in the cache controller.
Browse files Browse the repository at this point in the history
  • Loading branch information
howbazaar committed Jan 17, 2020
1 parent f31e3ad commit 47c80ad
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 14 deletions.
14 changes: 14 additions & 0 deletions core/cache/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ func (c *Controller) loop() error {
c.updateUnit(ch)
case RemoveUnit:
err = c.removeUnit(ch)
case RelationChange:
c.updateRelation(ch)
case RemoveRelation:
err = c.removeRelation(ch)
case BranchChange:
c.updateBranch(ch)
case RemoveBranch:
Expand Down Expand Up @@ -303,6 +307,16 @@ func (c *Controller) removeUnit(ch RemoveUnit) error {
return errors.Trace(c.removeResident(ch.ModelUUID, func(m *Model) error { return m.removeUnit(ch) }))
}

// updateRelation adds or updates the relation in the specified model.
func (c *Controller) updateRelation(ch RelationChange) {
c.ensureModel(ch.ModelUUID).updateRelation(ch, c.manager)
}

// removeRelation removes the relation from the cached model.
func (c *Controller) removeRelation(ch RemoveRelation) error {
return errors.Trace(c.removeResident(ch.ModelUUID, func(m *Model) error { return m.removeRelation(ch) }))
}

// updateMachine adds or updates the machine in the specified model.
func (c *Controller) updateMachine(ch MachineChange) {
c.ensureModel(ch.ModelUUID).updateMachine(ch, c.manager)
Expand Down
37 changes: 37 additions & 0 deletions core/cache/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (s *ControllerSuite) TestAddModel(c *gc.C) {
"charm-count": 0,
"machine-count": 0,
"unit-count": 0,
"relation-count": 0,
"branch-count": 0,
}})

Expand Down Expand Up @@ -280,6 +281,38 @@ func (s *ControllerSuite) TestRemoveUnit(c *gc.C) {
s.AssertResident(c, unit.CacheId(), false)
}

func (s *ControllerSuite) TestAddRelation(c *gc.C) {
controller, events := s.new(c)
s.processChange(c, relationChange, events)

mod, err := controller.Model(relationChange.ModelUUID)
c.Assert(err, jc.ErrorIsNil)
c.Check(mod.Report()["relation-count"], gc.Equals, 1)

relation, err := mod.Relation(relationChange.Key)
c.Assert(err, jc.ErrorIsNil)
s.AssertResident(c, relation.CacheId(), true)
}

func (s *ControllerSuite) TestRemoveRelation(c *gc.C) {
controller, events := s.new(c)
s.processChange(c, relationChange, events)

mod, err := controller.Model(relationChange.ModelUUID)
c.Assert(err, jc.ErrorIsNil)
relation, err := mod.Relation(relationChange.Key)
c.Assert(err, jc.ErrorIsNil)

remove := cache.RemoveRelation{
ModelUUID: modelChange.ModelUUID,
Key: relationChange.Key,
}
s.processChange(c, remove, events)

c.Check(mod.Report()["relation-count"], gc.Equals, 0)
s.AssertResident(c, relation.CacheId(), false)
}

func (s *ControllerSuite) TestAddBranch(c *gc.C) {
controller, events := s.new(c)
s.processChange(c, branchChange, events)
Expand Down Expand Up @@ -380,6 +413,10 @@ func (s *ControllerSuite) captureEvents(c *gc.C) <-chan interface{} {
send = true
case cache.RemoveUnit:
send = true
case cache.RelationChange:
send = true
case cache.RemoveRelation:
send = true
case cache.BranchChange:
send = true
case cache.RemoveBranch:
Expand Down
58 changes: 57 additions & 1 deletion core/cache/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func newModel(metrics *ControllerGauges, hub *pubsub.SimpleHub, res *Resident) *
charms: make(map[string]*Charm),
machines: make(map[string]*Machine),
units: make(map[string]*Unit),
relations: make(map[string]*Relation),
branches: make(map[string]*Branch),
}
return m
Expand All @@ -59,6 +60,7 @@ type Model struct {
charms map[string]*Charm
machines map[string]*Machine
units map[string]*Unit
relations map[string]*Relation
branches map[string]*Branch
}

Expand Down Expand Up @@ -105,6 +107,7 @@ func (m *Model) Report() map[string]interface{} {
"charm-count": len(m.charms),
"machine-count": len(m.machines),
"unit-count": len(m.units),
"relation-count": len(m.relations),
"branch-count": len(m.branches),
}
}
Expand All @@ -117,7 +120,7 @@ func (m *Model) Branches() []Branch {
i := 0
for _, b := range m.branches {
branches[i] = b.copy()
i += 1
i++
}

m.mu.Unlock()
Expand Down Expand Up @@ -341,6 +344,59 @@ func (m *Model) removeUnit(ch RemoveUnit) error {
return nil
}

// Relation returns the relation with the specified key.
// If the relation is not found, a NotFoundError is returned.
func (m *Model) Relation(key string) (Relation, error) {
defer m.doLocked()()

relation, found := m.relations[key]
if !found {
return Relation{}, errors.NotFoundf("relation %q", key)
}
return relation.copy(), nil
}

// Relations returns all relations in the model.
func (m *Model) Relations() map[string]Relation {
m.mu.Lock()

relations := make(map[string]Relation, len(m.relations))
for key, r := range m.relations {
relations[key] = r.copy()
}

m.mu.Unlock()
return relations
}

// updateRelation adds or updates the relation in the model.
func (m *Model) updateRelation(ch RelationChange, rm *residentManager) {
m.mu.Lock()

relation, found := m.relations[ch.Key]
if !found {
relation = newRelation(m, rm.new())
m.relations[ch.Key] = relation
}
relation.setDetails(ch)

m.mu.Unlock()
}

// removeRelation removes the relation from the model.
func (m *Model) removeRelation(ch RemoveRelation) error {
defer m.doLocked()()

relation, ok := m.relations[ch.Key]
if ok {
if err := relation.evict(); err != nil {
return errors.Trace(err)
}
delete(m.relations, ch.Key)
}
return nil
}

// updateMachine adds or updates the machine in the model.
func (m *Model) updateMachine(ch MachineChange, rm *residentManager) {
m.mu.Lock()
Expand Down
1 change: 1 addition & 0 deletions core/cache/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (s *ModelSuite) TestReport(c *gc.C) {
"charm-count": 0,
"machine-count": 0,
"unit-count": 0,
"relation-count": 0,
"branch-count": 0,
})
}
Expand Down
1 change: 1 addition & 0 deletions core/cache/package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func (*ImportSuite) TestImports(c *gc.C) {
"core/life",
"core/lxdprofile",
"core/network",
"core/permission",
"core/settings",
"core/status",
})
Expand Down
54 changes: 54 additions & 0 deletions core/cache/relation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package cache

// Relation represents a relation in a cached model.
type Relation struct {
// Resident identifies the relation as a type-agnostic cached entity
// and tracks resources that it is responsible for cleaning up.
*Resident

model *Model
details RelationChange
}

func newRelation(model *Model, res *Resident) *Relation {
return &Relation{
Resident: res,
model: model,
}
}

// Note that these property accessors are not lock-protected.
// They are intended for calling from external packages that have retrieved a
// deep copy from the cache.

// Key returns the key of this relation.
func (r *Relation) Key() string {
return r.details.Key
}

// Endpoints returns the endpoints for this relation.
func (r *Relation) Endpoints() []Endpoint {
return r.details.Endpoints
}

func (r *Relation) setDetails(details RelationChange) {
// If this is the first receipt of details, set the removal message.
if r.removalMessage == nil {
r.removalMessage = RemoveRelation{
ModelUUID: details.ModelUUID,
Key: details.Key,
}
}

r.setStale(false)
}

// copy returns a copy of the unit, ensuring appropriate deep copying.
func (r *Relation) copy() Relation {
cr := *r
cr.details = cr.details.copy()
return cr
}
28 changes: 28 additions & 0 deletions core/cache/relation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package cache_test

import (
"github.com/juju/juju/core/cache"
)

// Mostly a placeholder file at this stage.

var relationChange = cache.RelationChange{
ModelUUID: "model-uuid",
Key: "provider:ep consumer:ep",
Endpoints: []cache.Endpoint{
{
Application: "provider",
Name: "ep",
Role: "provider",
Interface: "foo",
}, {
Application: "consumer",
Name: "ep",
Role: "requires",
Interface: "foo",
},
},
}
1 change: 1 addition & 0 deletions core/cache/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func (u *Unit) setDetails(details UnitChange) {
u.details = details
toPublish := u.copy()
if machineChange || u.details.Subordinate {
// TODO thumper: check this, it looks like we are publishing too often.
u.model.hub.Publish(modelUnitAdd, toPublish)
}
// Publish change event for those that may be waiting.
Expand Down
26 changes: 13 additions & 13 deletions worker/modelcache/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ func (c *cacheWorker) translateRelation(d multiwatcher.Delta) interface{} {
if d.Removed {
return cache.RemoveRelation{
ModelUUID: id.ModelUUID,
Name: id.ID,
Key: id.ID,
}
}

Expand All @@ -479,22 +479,22 @@ func (c *cacheWorker) translateRelation(d multiwatcher.Delta) interface{} {
}

endpoints := make([]cache.Endpoint, len(value.Endpoints))
for i, ep := range value.Endpoints{
endpoints[i] := cache.Endpoint{
Application: value.ApplicationName,
Name: value.Relation.Name,
Role: value.Relation.Role,
Interface: value.Relation.Interface,
Optional: value.Relation.Optional,
Limit: value.Relation.Limit,
Scope: value.Relation.Scope,
for i, ep := range value.Endpoints {
endpoints[i] = cache.Endpoint{
Application: ep.ApplicationName,
Name: ep.Relation.Name,
Role: ep.Relation.Role,
Interface: ep.Relation.Interface,
Optional: ep.Relation.Optional,
Limit: ep.Relation.Limit,
Scope: ep.Relation.Scope,
}
}

return cache.RelationChange{
ModelUUID: value.ModelUUID,
Key: value.Key,
Endpoints: endpoints,
ModelUUID: value.ModelUUID,
Key: value.Key,
Endpoints: endpoints,
}
}

Expand Down

0 comments on commit 47c80ad

Please sign in to comment.