Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor itopo initialization #3661

Merged
merged 1 commit into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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