Adding support for “tree” style configs is also on my wish list. I tend to use the config for logger
as an example of what I would like to improve.
Regarding validation, my current hope is that it might be possible to leverage the erlang type system to describe what types should be allowed and then also allow for custom logic when some values depend on each other. The problem with using the type system for it is that you would like to be able to re-use the types for usage by dialyzer and also edoc/erl_docgen, so I wonder if it is possible to make all these tools agree on what the type syntax means.
For example, the way that I do scheduler config:
-type scheduler() ::
#{
online => 1..1024,
available => 1..1024,
busy_wait_threashold => none|very_short|short|medium|long|very_long,
stacksize => 20..8192,
wakeup_threshold => very_low|low|medium|high|very_high
}.
-type schedulers() ::
#{
normal => scheduler(),
dirty => #{ cpu => scheduler(),
io => scheduler() },
%% +sbt
bind_type =>
default_bind | no_node_processor_spread |
no_node_thread_spread | no_spread |
processor_spread | spread | thread_spread |
thread_no_node_processor_spread | unbound,
load =>
#{
%% +scl
compact => boolean(),
%% +sub
utilization => boolean()
},
%% +sct
topology => string(),
%% +sfwi
forced_wakeup_interval => integer(),
%% +spp
port_parallelism => boolean(),
%% +swct
wake_cleanup_threashold => very_eager | eager | medium | lazy | very_lazy,
%% +sws
wakeup_strategy => default | legacy
}.
and then also validate that online > available scheduler using code:
check_env(Env, Online, [schedulers, dirty, cpu, online] = Path) ->
Available = get_path([schedulers, dirty, cpu, available],
Env, erlang:system_info(dirty_cpu_schedulers)),
if Online > Available ->
[{error, invalid_value,
fun() ->
io_lib:format(
"invalid value: ~p.~n "
"Number of online schedulers (~p) must be less than or equal to available (~p)",
[Online, Online, Available])
end, Path}];
true ->
[]
end;
check_env(_, _, _) ->
[].