Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions