Skip to content

Running refresh: avoid TreeExport/Proto round-trip for in-process staging → syncTree (pointer hand-off) #453

@steiler

Description

@steiler

Summary

Several Running refresh paths build a staging config tree (schema resolution, Entry graph, leaf variants), then TreeExport to tree_persist / Intent, then merge into the canonical store syncTree via ImportConfig using ProtoTreeImporter.

That implies extra work: full structure build, export walk, per-leaf protobuf marshal/unmarshal, and import/schema binding again on the destination tree.

The TreeProto step is a good interchange format for persistence, RPC, or tests, but for in-process “staging tree → canonical syncTree” it is largely redundant.

This is not specific to gNMI GET; the same pattern appears wherever staging is filled then handed off through TreeProto, for example:

  • gNMI GET syncpkg/datastore/target/gnmi/get.go (internalGetSync: notifications → tree → TreeExportApplyToRunning + proto.NewProtoTreeImporter)
  • gNMI stream syncpkg/datastore/target/gnmi/stream.go (same export → ApplyToRunning pattern)

Other southbound paths may already use a different adapter into ApplyToRunning (e.g. NETCONF can return an importer directly); the improvement still applies whenever the handoff is “built api.Entry tree → TreeExport → ProtoTreeImporter” for the same process.

Proposed solution

Pointer hand-off, not TreeProto for in-process handoffs:

  • Add an ImportConfigAdapter whose traversal reads from the existing in-memory tree (api.Entry graph or a thin index), and run ImportConfig once against the datastore syncTree under the existing ApplyToRunning contract (deletes, revert snapshot, processors, locking).
  • Keep TreeExport + ProtoTreeImporter where a serialized Intent is genuinely required (persistence, cross-process, shared contract with intent storage, tests).

Goals

  • Drop the encode/decode and second full traversal when source and destination trees live in the same binary and epoch.
  • Preserve ApplyToRunning semantics end-to-end.

References

  • pkg/datastore/target/gnmi/get.go — GET sync
  • pkg/datastore/target/gnmi/stream.go — stream sync
  • pkg/datastore/sync.goApplyToRunning / ImportConfig
  • pkg/datastore/target/netconf/sync.go — calls ApplyToRunning with a target-provided importer (pattern may differ; still the same merge API)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions