Summary

Vespa configuration is a pipeline. Config definitions (.def files) are compiled into typed config classes; a ZooKeeper-backed config server computes concrete config from a model of the application; each node runs a config proxy that caches config and re-serves it over jrt RPC; local daemons and application components subscribe through a shared ConfigSubscriber API keyed by a configId, tracking a monotonically increasing generation. This note maps that flow onto inspected sources in configgen, config-lib, config, configd, config-proxy, and the configserver/config-model READMEs. See also config-admin for the administrative surface and container-jdisc for the component side that consumes config.

Key mechanisms

  • Definition and generation: configgen generates config classes from .def files, normally consumed through the config-class-plugin maven plugin (configgen/README). Generated classes extend config-lib’s abstract ConfigInstance (config-lib/src/main/java/com/yahoo/config/ConfigInstance.java:14); its nested Builder interface exposes dispatchGetConfig and getDefName/getDefNamespace/getDefMd5, backed by static fields CONFIG_DEF_NAME / CONFIG_DEF_NAMESPACE / CONFIG_DEF_MD5 (lines 16-27, 45-53). config-lib/README.md warns there is only one version of this library in a multi-version config server, so API and serialized data must stay backwards compatible; configdefinitions/README holds common cross-module defs.
  • Model to server: config-model/README describes Java models derived from application packages “used to create configuration for the distributed components of the system”; configserver/README calls the config server “Zookeeper backed” (state layout deferred to GDN-NOTE-0037).
  • Subscription API: ConfigSubscriber::subscribe(configId, timeout) returns a ConfigHandle; nextConfig / nextGeneration poll for updates, and once called the subscription set is FROZEN; getGeneration returns the current generation number (config/src/vespa/config/subscription/configsubscriber.h:19-23, 59-70, 73-84, 90).
  • Local daemon (configd): the sentinel’s ConfigOwner holds a ConfigSubscriber plus a ConfigHandle and subscribes per configId (configd/src/apps/sentinel/config-owner.h:16-20, config-owner.cpp:18); it re-applies config when nextGenerationNow() returns true (config-owner.cpp:35-39). Manager maps service names to child processes in ServiceMap members and applies updates via doConfigure() (manager.h:33-54). vespa-sentinel-cmd drives the sentinel over FRT RPC methods sentinel.ls, sentinel.service.restart / start / stop (configd/src/apps/cmd/main.cpp:23-26).
  • Delivery via config proxy: the proxy exposes jrt method config.v3.getConfig, request type “s”, response “sx” (config/src/main/java/com/yahoo/vespa/config/JRTMethods.java:15-17). ConfigProxyRpcServer declares it plus ping, listCachedConfig, invalidateCache, updateSources, setMode, and requires Capability.CONFIGPROXY__CONFIG_API on the config method (config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java:42-50, 86-128). Responses are served from MemoryCache, a ConcurrentHashMap keyed by ConfigCacheKey, with a dump directory under var/vespa/cache/config (MemoryCache.java:18-27); misses go upstream through RpcConfigSourceClient, an RPC client to a config source (RpcConfigSourceClient.java:12-14).

Open questions

  • Where per-config payload bytes and generation numbers are produced server-side (configserver session/config-model packages not read in this pass).
  • How the sentinel chooses between process restart and live reload on a new generation (configd/src/apps/sentinel/service.cpp not read).
  • Long-poll semantics and default timeouts of nextGeneration against the proxy (config/src/vespa/config/subscription/configsubscriber.cpp not read).