Skip to content

Commit

Permalink
Refactor itopo initialization (#3661)
Browse files Browse the repository at this point in the history
Most of the initializers used default values. Changing to
a config struct makes the itopo package easier to refactor.
  • Loading branch information
scrye authored Feb 7, 2020
1 parent f80a268 commit f3ad3a3
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 232 deletions.
1 change: 0 additions & 1 deletion acceptance/topo_sd_reload/testdata/topology_reload.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
}
},
"ColibriService": {},
"DiscoveryService": {},
"Attributes": [
"authoritative",
"core",
Expand Down
2 changes: 1 addition & 1 deletion go/border/brconf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (cfg *BRConf) loadTopo(id string) error {
return nil
}

// initTopo initializesthe entries related to topo in the config.
// initTopo initializes the entries related to topo in the config.
func (cfg *BRConf) initTopo(id string, topo topology.Topology) error {
cfg.Topo = topo
cfg.IA = cfg.Topo.IA()
Expand Down
18 changes: 12 additions & 6 deletions go/border/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,16 @@ func (r *Router) setup() error {
return err
}
// Initialize itopo.
itopo.Init(r.Id, proto.ServiceType_br, itopo.Callbacks{})
if _, _, err := itopo.SetStatic(conf.Topo); err != nil {
itopo.Init(
&itopo.Config{
ID: r.Id,
Svc: proto.ServiceType_br,
},
)
if err := itopo.Update(conf.Topo); err != nil {
return err
}
conf.Topo = itopo.Get()
// Setup new context.
if err = r.setupCtxFromConfig(conf); err != nil {
return err
Expand Down Expand Up @@ -120,13 +126,13 @@ func (r *Router) setupCtxFromConfig(config *brconf.BRConf) error {
// We want to keep in sync itopo and the context that is set.
// We attempt to set the context with the topology that will be current
// after setting itopo. If setting itopo fails in the end, we rollback the context.
tx, err := itopo.BeginSetStatic(config.Topo.Writable())
tx, err := itopo.BeginUpdate(config.Topo.Writable())
if err != nil {
return err
}
// Set config to use the appropriate topology. The returned topology is
// not necessarily the same as config.Topo. It can be another static topology.
newConf, err := brconf.WithNewTopo(r.Id, topology.FromRWTopology(tx.Get()), config)
newConf, err := brconf.WithNewTopo(r.Id, tx.Get(), config)
if err != nil {
return err
}
Expand All @@ -138,7 +144,7 @@ func (r *Router) setupCtxFromConfig(config *brconf.BRConf) error {
func (r *Router) setupCtxFromStatic(topo *topology.RWTopology) (bool, error) {
r.setCtxMtx.Lock()
defer r.setCtxMtx.Unlock()
tx, err := itopo.BeginSetStatic(topo)
tx, err := itopo.BeginUpdate(topo)
return r.setupCtxFromTopoUpdate(tx, err)
}

Expand All @@ -151,7 +157,7 @@ func (r *Router) setupCtxFromTopoUpdate(tx itopo.Transaction, err error) (bool,
return false, nil
}
log.Trace("====> Setting up new context from topology update")
newConf, err := brconf.WithNewTopo(r.Id, topology.FromRWTopology(tx.Get()), rctx.Get().Conf)
newConf, err := brconf.WithNewTopo(r.Id, tx.Get(), rctx.Get().Conf)
if err != nil {
return false, err
}
Expand Down
13 changes: 9 additions & 4 deletions go/cs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,13 +715,18 @@ func setup() error {
if err := cfg.Validate(); err != nil {
return common.NewBasicError("Unable to validate config", err)
}
clbks := itopo.Callbacks{UpdateStatic: handleTopoUpdate}
// Use CS for monolith for now
itopo.Init(cfg.General.ID, proto.ServiceType_cs, clbks)
topo, err := topology.FromJSONFile(cfg.General.Topology)
if err != nil {
return common.NewBasicError("Unable to load topology", err)
}
// Use CS for monolith for now
itopo.Init(
&itopo.Config{
ID: cfg.General.ID,
Svc: proto.ServiceType_cs,
Callbacks: itopo.Callbacks{OnUpdate: handleTopoUpdate},
},
)
return initTopo(topo)
}

Expand All @@ -733,7 +738,7 @@ func handleTopoUpdate() {
}

func initTopo(topo topology.Topology) error {
if _, _, err := itopo.SetStatic(topo); err != nil {
if err := itopo.Update(topo); err != nil {
return serrors.WrapStr("Unable to set initial static topology", err)
}
infraenv.InitInfraEnvironment(cfg.General.Topology)
Expand Down
2 changes: 1 addition & 1 deletion go/lib/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func ReloadTopology(topologyPath string) {
log.Error("Unable to reload topology", "err", err)
return
}
if _, _, err := itopo.SetStatic(topo); err != nil {
if err := itopo.Update(topo); err != nil {
log.Error("Unable to set topology", "err", err)
return
}
Expand Down
138 changes: 16 additions & 122 deletions go/lib/infra/modules/itopo/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,126 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package itopo stores the static and dynamic topology. Client packages
that grab a reference with Get are guaranteed to receive a stable
snapshot of the topology. The returned value is the topology that is
currently active.
There are two types of topologies, the static and the dynamic topology.
For more information see lib/discovery.
Initialization
The package must be initialized with Init. In subsequent updates through
SetStatic or SetDynamic, the new topology is checked whether it is
compatible with the previous version. The rules differ between services.
If the dynamic topology is set, the initializing client should start
the periodic cleaner to evict expired dynamic topologies.
Updates
The update of the topology is only valid if a set of constraints is
met. The constraints differ between dynamic and static topology, and
also between the initialized service type.
In a static topology update, when the diff is empty, the static
topology is only updated if it expires later than the current static.
Otherwise, SetStatic succeeds and indicates that the in-memory copy
has not been updated.
A static topology update can force the dynamic topology to be dropped,
if it does no longer meet the constraints.
Constraints
The topology is split into five parts. An update is valid under the
constraints, if the constraints for each part are met.
Immutable:
This part may not differ from the initial static topology.
Mutable:
This part may differ from the initial static topology. It may also
differ between the currently active static and dynamic topology.
Semi-Mutable:
This part may differ between static topology versions. However, it
may not differ between the current dynamic and static topology.
If an update to the static topology modifies this part, the dynamic
topology is dropped.
Time:
This part is ignored when validating the constraints. It is used
to determine if a topology shall be updated if there are no
differences in the other parts.
Ignored:
This part is always ignored.
Default Topology Split
The topology file for default initialization (calling Init) is split
into immutable, mutable, time and ignored.
ISD_AS Immutable
Core Immutable
Overlay Immutable
MTU Immutable
Service Entries Mutable
BorderRouter Entries Mutable
Timestamp Time
TTL Time
TimestampHuman Ignored
Service Topology Split
The topology file for services is split into immutable, mutable,
time and ignored.
ISD_AS Immutable
Core Immutable
Overlay Immutable
MTU Immutable
OwnSvcType[OwnID] Immutable // The service entry for the initialized element.
Service Entries Mutable // Except OwnSvcType[OwnID].
BorderRouter Entries Mutable
Timestamp Time
TTL Time
TimestampHuman Ignored
Border Router Topology Split
The topology file for border routers is split into immutable,
semi-mutable, mutable, time and ignored.
ISD_AS Immutable
Core Immutable
Overlay Immutable
MTU Immutable
BorderRouters[OwnId][InternalAddrs] Immutable // Internal address of initialized router.
BorderRouters[OwnId][CtrlAddr] Immutable // Control address of initialized router.
BorderRouters[OwnId][Interfaces] Semi-Mutable // Interfaces of initialized router.
Service Entries Mutable
BorderRouter Entries Mutable // Except BorderRouters[OwnId].
Timestamp Time
TTL Time
TimestampHuman Ignored
Callbacks
The client package can register callbacks to be notified about
certain events.
*/
// Package itopo stores topology state and manages topology updates for an application.
//
// The package must be initialized with Init. In subsequent updates through Update, the new
// topology is checked whether it is compatible with the previous version. The rules differ between
// services.
//
// Updates
//
// The update of the topology is only valid if a set of constraints is met. The constraints differ
// between the initialized service types.
//
// In a topology update, when the diff is empty, the topology is only updated if it
// expires later than the current topology. Otherwise, Update succeeds and indicates that the
// in-memory copy has not been updated.
//
// The client package can register callbacks to be notified about certain events.
package itopo
Loading

0 comments on commit f3ad3a3

Please sign in to comment.