Proposal: decouple config structs used in garage and garage_model crates #699
Labels
No labels
action
check-aws
action
discussion-needed
action
for-external-contributors
action
for-newcomers
action
more-info-needed
action
need-funding
action
triage-required
kind
correctness
kind
ideas
kind
improvement
kind
performance
kind
testing
kind
usability
kind
wrong-behavior
prio
critical
prio
low
scope
admin-api
scope
background-healing
scope
build
scope
documentation
scope
k8s
scope
layout
scope
metadata
scope
ops
scope
rpc
scope
s3-api
scope
security
scope
telemetry
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Deuxfleurs/garage#699
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The current configuration handling in
garage
is difficult due to two reasons:util
,db
,config
The proposal is to split and re-arrange config data types into two sets:
First, a
garage
binary configuration types ingarage
crate. Usedexclusively for parsing, validating, merging config from ENV, CLI, TOML.
Minimal to no dependency on internal crates like
garage_db
.Second, a
garage
serverstruct
types ingarage_model
crate. Usedexclusively for passing and storing config in
Garage
struct. No parsing/serde logic,but allow re-use of types from lower-level, internal crates.
The config data flow would start with parsing binary config types, then
fallibly converting them
garage
server config and passing it toGarage
struct.
Advantages
Disadvantages
NOTE: The need for conversion logic is toss-up. On one side, it is a code that
has to be maintained. On other, it provides bridge between data type sets,
allowing us to change one side but not the other.
Implementation
The split implementation can be fairly minimal:
Config
struct
structure same, just duplicate it into two crates.garage::config
crate would implementserde
logicgarage::config
crate would implement conversion logicgarage_model::config
would be plain storage without any logicOutcomes
Implementing the proposal as described in previous section
It will allow us number of follow-up clean-ups and refactorings:
garage_model::config
variantstruct
methodsWe will be able to do those without making the code hard to read by mixing
parsing/handling logic in one data type.
@lx To make it explicit, I'm willing to work on the proposal implementation and possibly some follow-up refactorings too.
Hello @zdenek.crha , thank you very much for the proposal. I like your proposal, and I think we can even make it a bit more clean by not just duplicating everything in the garage_model crate, but by splitting the different config sections into the relevant crates:
Anyway, it would be great to have your work on this, so feel free to get started. If you'd like i can give feedback on your code as you go.
@lx I agree we can go further with the split. The duplication I suggested was just to get the split as fast as possible. I actually have pretty long list of possible changes that could be done afterwards :-)
I will use your suggestions for splitting the config to relevant classes and have a go at it.
If we need to split those re-used structs from
garage_web
,garage_api
to support relaxed config parsing ingarage
and strict modeling ingarage_model
, we can do it later.I have started on the config changes and run into issue I have not expected. The
garage_rpc
crate relies ongarage_util::config::Config
struct and the moves and splits would result in dependency cycles between various internal crates.The best approach I came could come with is to refactor
garage_rpc
to not useConfig
struct:It is used only in
System::new()
method, where pieces of config are extracted, transformed and used as part ofSystem
. TheConfig
is not held, it is used just for passing config in. At the same time, there are many pieces fromConfig
used, it makes no sense to pass them in as separate arguments.Idea I play with is to turn
System::new()
method into builder struct, so that we could configure all related and unrelated parts piece-by-piece. I'll iterate on it and see if I can make it work or not.I'm not a big fan myself of the builder pattern because to my eyes it looks like mostly boilerplate. Is there not a way where we could regroup the exact subset of configuration parameters used by
System::new
in a specific struct and just pass that as an argument? If not, yes please go ahead and do what you think is good.@lx I have not considered that approach. Will check and use it if possible.
@lx Just a quick update - I have not had much energy to spend on garage in last few month, but I'm still interested in working on this.