Skip to content
Browse files
Allow dynamic classes in is_valid_class
This adds support for dynamic classes in IOQ2. Before this change, the
allowed set of classes was fixed and hardcoded, with no way for 3rd
party IO traffic to be prioritized, and similarly, no way for 3rd party
IO traffic to bypass IOQ based on config settings. This change switches
to checking to see if there's a declared IO priority value in the
classes config, and if so it is treated as a valid value. It's worth
noting that because `ioq_config:set_class_config` uses the
`is_valid_class` check, you must use `config:set` directly to declare an
initial priority for the dynamic channel before being able to use the
`ioq_config` helpers.

This change was motivated by not being able to bypass search in the
Dreyfus project, as it piggy-backed off of `interactive` and
`view_update` channels. That was rectified in [1], and now Dreyfus uses
the `search` IOQ channel. As that is not used in CouchDB directly, this
commit adds the dynamic class support based off of config values, rather
than specifically hardcoding search, so that it can be used by any 3rd
party services running IO traffic through IOQ.

[1] cloudant-labs/dreyfus@75d86c4
  • Loading branch information
chewbranca committed Apr 12, 2019
1 parent 08c6bbb commit d6e7a78ccffba459860df6ffcfd9e022569118de
Showing 2 changed files with 44 additions and 2 deletions.
@@ -135,8 +135,19 @@ set_user_config(User, Value, Reason) ->
ok = set_config(?IOQ2_USERS_CONFIG, User, Value, Reason).

is_valid_class(Class) ->
lists:member(Class, ioq_classes()).
is_valid_class(Class) when is_atom(Class) ->
case lists:member(Class, ioq_classes()) of
true ->
false ->
SClass = atom_to_list(Class),
case config:get(?IOQ2_CLASSES_CONFIG, SClass, undefined) of
undefined ->
_ ->

check_float_value(Value) when is_float(Value) ->
@@ -260,3 +260,34 @@ check_bypass_configs(_) ->
ok = ioq_config:set_bypass(interactive, true, "Bypassing interactive"),
Value = config:get_boolean("ioq2.bypass", "interactive", false),
?_assertEqual(true, Value).

valid_classes_test_() ->
"Test ioq_config is_valid_class logic",
fun() -> test_util:start_applications([config, couch_log]) end,
fun(_) -> test_util:stop_applications([config, couch_log]) end,
fun check_default_classes/1,
fun check_undeclared_class/1,
fun check_declared_class/1

check_default_classes(_) ->
Classes = [C || {C, _P} <- ?DEFAULT_CLASS_PRIORITIES],
[?_assert(ioq_config:is_valid_class(C)) || C <- Classes].

check_undeclared_class(_) ->
?_assert(not ioq_config:is_valid_class(search)).

check_declared_class(_) ->
config:set(?IOQ2_CLASSES_CONFIG, "search", "1.0", false),

0 comments on commit d6e7a78

Please sign in to comment.