Harvester is a configuration library which helps setting up and monitoring configuration values in order to dynamically
reconfigure your application.
Configuration can be obtained from the following sources:
-flag=valueThe order is applied as it is listed above. Consul seeder and monitor are optional and will be used only if Harvester is created with the above components.
Harvester expects a go structure with tags which defines one or more of the above like the following:
type Config struct {
IndexName sync.String `seed:"customers-v1"`
CacheRetention sync.Int64 `seed:"86400" env:"ENV_CACHE_RETENTION_SECONDS"`
LogLevel sync.String `seed:"DEBUG" flag:"loglevel"`
Signature sync.String `file:"signature.txt"`
Sandbox sync.Bool `seed:"true" env:"ENV_SANDBOX" consul:"/config/sandbox-mode"`
AccessToken sync.Secret `seed:"defaultaccesstoken" env:"ENV_ACCESS_TOKEN" consul:"/config/access-token"`
WorkDuration sync.TimeDuration `seed:"1s" env:"ENV_WORK_DURATION" consul:"/config/work-duration"`
OpeningBalance sync.Float64 `seed:"0.0" env:"ENV_OPENING_BALANCE" redis:"opening-balance"`
}
The above defines the following fields:
customers-v118, and if exists, overridden with whatever value the env var ENV_CACHE_RETENTION_SECONDS holdsDEBUG, and if exists, overridden with whatever value the flag loglevel holdstrue, and if exists, overridden with whatever value the env var ENV_SANDBOX holds and then from Consul if the consul seeder and/or watcher are provided.1s, and if exists, overridden with whatever value the env var ENV_WORK_DURATION holds and then from Consul if the consul seeder and/or watcher are provided.0.0, and if exists, overridden with whatever value the env var ENV_OPENING_BALANCE holds and then from Redis if the redis seeder and/or watcher are provided.The fields have to be one of the types that the sync package supports in order to allow concurrent read and write to the fields. The following types are supported:
For sensitive configuration (passwords, tokens, etc.) that shouldn't be printed in log, you can use the Secret flavor of sync types. If one of these is selected, then at harvester log instead of the real value the text *** will be displayed.
Harvester has a seeding phase and an optional monitoring phase.
Conditions where seeding fails:
Harvester allows the creation of custom getters which are used by the seeder and implement the following interface:
type Getter interface {
Get(key string) (string, error)
}
Seed and env tags are supported by default, the Consul getter has to be setup when creating a Harvester with the builder.
Harvester allows for dynamically changing the config value by monitoring a source. The following sources are available:
This feature have to be setup when creating a Harvester with the builder.
The Harvester builder pattern is used to create a Harvester instance. The builder supports setting up:
h, err := New(&cfg).
WithConsulSeed("address", "dc", "token").
WithConsulMonitor("address", "dc", "token").
WithRedisSeed(redisClient).
WithRedisMonitor(redisClient, 10*time.Millisecond).
Create()
The above snippet set's up a Harvester instance with Consul and Redis seed and monitor.
In order to be able to monitor the changes in the configuration we provide a way to notify when a change is happening via the builder.
h, err := harvester.New(&cfg).WithNotification(chNotify).Create()
...
Consul has support for versioning (ModifyIndex) which allows us to change the value only if the version is higher than the one currently.
Head over to examples readme on how to use harvester
Please note that this project is released with a Contributor Code of Conduct. By participating in this project and its community you agree to abide by those terms.
$ claude mcp add harvester \
-- python -m otcore.mcp_server <graph>