TD-298: Drop support for tag refs (#7)

This commit is contained in:
Alexey S 2022-06-06 15:57:57 +03:00 committed by GitHub
parent ff4cfefb61
commit 62c32434c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 105 additions and 120 deletions

View File

@ -13,7 +13,7 @@
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},2},
{<<"mg_proto">>,
{git,"https://github.com/valitydev/machinegun-proto.git",
{ref,"b43d6fd0939ee4029ec8873dbd16f3c5fbe4a95c"}},
{ref,"7d780d5aa445e37b4816ac8a433bfaffe3715f63"}},
0},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},2},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2},

View File

@ -11,9 +11,7 @@
-module(machinery).
-type namespace() :: atom().
-type ref() :: id() | {tag, tag()}.
-type id() :: binary().
-type tag() :: binary().
-type args(T) :: T.
-type response(T) :: T.
-type error(T) :: T.
@ -44,8 +42,6 @@
-export_type([namespace/0]).
-export_type([id/0]).
-export_type([tag/0]).
-export_type([ref/0]).
-export_type([range/0]).
-export_type([args/1]).
-export_type([response/1]).
@ -134,34 +130,34 @@ start(NS, ID, Args, Backend) ->
{Module, Opts} = machinery_utils:get_backend(Backend),
machinery_backend:start(Module, NS, ID, Args, Opts).
-spec call(namespace(), ref(), args(_), backend(_)) -> {ok, response(_)} | {error, notfound}.
call(NS, Ref, Args, Backend) ->
call(NS, Ref, {undefined, undefined, forward}, Args, Backend).
-spec call(namespace(), id(), args(_), backend(_)) -> {ok, response(_)} | {error, notfound}.
call(NS, ID, Args, Backend) ->
call(NS, ID, {undefined, undefined, forward}, Args, Backend).
-spec call(namespace(), ref(), range(), args(_), backend(_)) -> {ok, response(_)} | {error, notfound}.
call(NS, Ref, Range, Args, Backend) ->
-spec call(namespace(), id(), range(), args(_), backend(_)) -> {ok, response(_)} | {error, notfound}.
call(NS, ID, Range, Args, Backend) ->
{Module, Opts} = machinery_utils:get_backend(Backend),
machinery_backend:call(Module, NS, Ref, Range, Args, Opts).
machinery_backend:call(Module, NS, ID, Range, Args, Opts).
-spec repair(namespace(), ref(), args(_), backend(_)) ->
-spec repair(namespace(), id(), args(_), backend(_)) ->
{ok, response(_)} | {error, notfound | working | {failed, machinery:error(_)}}.
repair(NS, Ref, Args, Backend) ->
repair(NS, Ref, {undefined, undefined, forward}, Args, Backend).
repair(NS, ID, Args, Backend) ->
repair(NS, ID, {undefined, undefined, forward}, Args, Backend).
-spec repair(namespace(), ref(), range(), args(_), backend(_)) ->
-spec repair(namespace(), id(), range(), args(_), backend(_)) ->
{ok, response(_)} | {error, notfound | working | {failed, machinery:error(_)}}.
repair(NS, Ref, Range, Args, Backend) ->
repair(NS, ID, Range, Args, Backend) ->
{Module, Opts} = machinery_utils:get_backend(Backend),
machinery_backend:repair(Module, NS, Ref, Range, Args, Opts).
machinery_backend:repair(Module, NS, ID, Range, Args, Opts).
-spec get(namespace(), ref(), backend(_)) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, Ref, Backend) ->
get(NS, Ref, {undefined, undefined, forward}, Backend).
-spec get(namespace(), id(), backend(_)) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, ID, Backend) ->
get(NS, ID, {undefined, undefined, forward}, Backend).
-spec get(namespace(), ref(), range(), backend(_)) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, Ref, Range, Backend) ->
-spec get(namespace(), id(), range(), backend(_)) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, ID, Range, Backend) ->
{Module, Opts} = machinery_utils:get_backend(Backend),
machinery_backend:get(Module, NS, Ref, Range, Opts).
machinery_backend:get(Module, NS, ID, Range, Opts).
%% Internal API

View File

@ -13,7 +13,6 @@
-type namespace() :: machinery:namespace().
-type id() :: machinery:id().
-type ref() :: machinery:ref().
-type range() :: machinery:range().
-type args() :: machinery:args(_).
-type backend_opts() :: machinery:backend_opts(_).
@ -35,16 +34,16 @@
start(Backend, Namespace, Id, Args, Opts) ->
Backend:start(Namespace, Id, Args, Opts).
-spec call(backend(), namespace(), ref(), range(), args(), backend_opts()) ->
-spec call(backend(), namespace(), id(), range(), args(), backend_opts()) ->
{ok, machinery:response(_)} | {error, notfound}.
call(Backend, Namespace, Ref, Range, Args, Opts) ->
Backend:call(Namespace, Ref, Range, Args, Opts).
call(Backend, Namespace, Id, Range, Args, Opts) ->
Backend:call(Namespace, Id, Range, Args, Opts).
-spec repair(backend(), namespace(), ref(), range(), args(), backend_opts()) ->
-spec repair(backend(), namespace(), id(), range(), args(), backend_opts()) ->
{ok, machinery:response(_)} | {error, {failed, machinery:error(_)} | notfound | working}.
repair(Backend, Namespace, Ref, Range, Args, Opts) ->
Backend:repair(Namespace, Ref, Range, Args, Opts).
repair(Backend, Namespace, Id, Range, Args, Opts) ->
Backend:repair(Namespace, Id, Range, Args, Opts).
-spec get(backend(), namespace(), ref(), range(), backend_opts()) -> {ok, machinery:machine(_, _)} | {error, notfound}.
get(Backend, Namespace, Ref, Range, Opts) ->
Backend:get(Namespace, Ref, Range, Opts).
-spec get(backend(), namespace(), id(), range(), backend_opts()) -> {ok, machinery:machine(_, _)} | {error, notfound}.
get(Backend, Namespace, Id, Range, Opts) ->
Backend:get(Namespace, Id, Range, Opts).

View File

@ -10,7 +10,6 @@
-include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl").
-type namespace() :: machinery:namespace().
-type ref() :: machinery:ref().
-type id() :: machinery:id().
-type range() :: machinery:range().
-type args(T) :: machinery:args(T).
@ -125,12 +124,12 @@ start(NS, ID, Args, Opts) ->
error({failed, NS, ID})
end.
-spec call(namespace(), ref(), range(), args(_), backend_opts()) -> {ok, response(_)} | {error, notfound}.
call(NS, Ref, Range, Args, Opts) ->
-spec call(namespace(), id(), range(), args(_), backend_opts()) -> {ok, response(_)} | {error, notfound}.
call(NS, Id, Range, Args, Opts) ->
Client = get_client(Opts),
Schema = get_schema(Opts),
SContext0 = build_schema_context(NS, Ref),
Descriptor = {NS, Ref, Range},
SContext0 = build_schema_context(NS, Id),
Descriptor = {NS, Id, Range},
{CallArgs, SContext1} = marshal({schema, Schema, {args, call}, SContext0}, Args),
case machinery_mg_client:call(marshal(descriptor, Descriptor), CallArgs, Client) of
{ok, Response0} ->
@ -141,16 +140,16 @@ call(NS, Ref, Range, Args, Opts) ->
{exception, #mg_stateproc_NamespaceNotFound{}} ->
error({namespace_not_found, NS});
{exception, #mg_stateproc_MachineFailed{}} ->
error({failed, NS, Ref})
error({failed, NS, Id})
end.
-spec repair(namespace(), ref(), range(), args(_), backend_opts()) ->
-spec repair(namespace(), id(), range(), args(_), backend_opts()) ->
{ok, response(_)} | {error, {failed, error(_)} | notfound | working}.
repair(NS, Ref, Range, Args, Opts) ->
repair(NS, Id, Range, Args, Opts) ->
Client = get_client(Opts),
Schema = get_schema(Opts),
SContext0 = build_schema_context(NS, Ref),
Descriptor = {NS, Ref, Range},
SContext0 = build_schema_context(NS, Id),
Descriptor = {NS, Id, Range},
{RepairArgs, SContext1} = marshal({schema, Schema, {args, repair}, SContext0}, Args),
case machinery_mg_client:repair(marshal(descriptor, Descriptor), RepairArgs, Client) of
{ok, Response0} ->
@ -165,14 +164,14 @@ repair(NS, Ref, Range, Args, Opts) ->
{exception, #mg_stateproc_NamespaceNotFound{}} ->
error({namespace_not_found, NS});
{exception, #mg_stateproc_MachineFailed{}} ->
error({failed, NS, Ref})
error({failed, NS, Id})
end.
-spec get(namespace(), ref(), range(), backend_opts()) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, Ref, Range, Opts) ->
-spec get(namespace(), id(), range(), backend_opts()) -> {ok, machine(_, _)} | {error, notfound}.
get(NS, Id, Range, Opts) ->
Client = get_client(Opts),
Schema = get_schema(Opts),
Descriptor = {NS, Ref, Range},
Descriptor = {NS, Id, Range},
case machinery_mg_client:get_machine(marshal(descriptor, Descriptor), Client) of
{ok, Machine0} ->
{Machine1, _Context} = unmarshal({machine, Schema}, Machine0),
@ -271,11 +270,11 @@ set_aux_state(undefined, ReceivedState) ->
set_aux_state(NewState, _) ->
NewState.
-spec build_schema_context(namespace(), ref()) -> machinery_mg_schema:context().
build_schema_context(NS, Ref) ->
-spec build_schema_context(namespace(), id()) -> machinery_mg_schema:context().
build_schema_context(NS, Id) ->
#{
machine_ns => NS,
machine_ref => Ref
machine_id => Id
}.
%% Marshalling

View File

@ -24,16 +24,10 @@ marshal(event_id, V) ->
marshal(integer, V);
marshal(namespace, V) ->
marshal(atom, V);
marshal(tag, V) ->
marshal(string, V);
marshal(ref, V) when is_binary(V) ->
{id, marshal(id, V)};
marshal(ref, {tag, V}) ->
{tag, marshal(tag, V)};
marshal(descriptor, {NS, Ref, Range}) ->
marshal(descriptor, {NS, ID, Range}) ->
#mg_stateproc_MachineDescriptor{
'ns' = marshal(namespace, NS),
'ref' = marshal(ref, Ref),
'ref' = {id, marshal(id, ID)},
'range' = marshal(range, Range)
};
marshal(range, {Cursor, Limit, Direction}) ->
@ -73,8 +67,6 @@ unmarshal(event_id, V) ->
unmarshal(integer, V);
unmarshal(namespace, V) ->
unmarshal(atom, V);
unmarshal(tag, V) ->
unmarshal(string, V);
%%
%% No unmarshalling for the decriptor required by the protocol so far.
%%

View File

@ -27,7 +27,7 @@
-type version() :: undefined | integer().
-type context() :: #{
machine_ref := machinery:ref(),
machine_id := machinery:id(),
machine_ns := machinery:namespace(),
created_at => machinery:timestamp(),
atom() => term()

View File

@ -7,7 +7,7 @@
% API
-type namespace() :: machinery:namespace().
-type ref() :: machinery:ref().
-type id() :: machinery:id().
-type range() :: machinery:range().
-type backend() :: machinery:backend(_).
@ -16,11 +16,11 @@
%% API
-spec modernize(namespace(), ref(), backend()) -> ok | {error, notfound}.
modernize(NS, Ref, Backend) ->
modernize(NS, Ref, {undefined, undefined, forward}, Backend).
-spec modernize(namespace(), id(), backend()) -> ok | {error, notfound}.
modernize(NS, Id, Backend) ->
modernize(NS, Id, {undefined, undefined, forward}, Backend).
-spec modernize(namespace(), ref(), range(), backend()) -> ok | {error, notfound}.
modernize(NS, Ref, Range, Backend) ->
-spec modernize(namespace(), id(), range(), backend()) -> ok | {error, notfound}.
modernize(NS, Id, Range, Backend) ->
{Module, Opts} = machinery_utils:get_backend(Backend),
machinery_modernizer_backend:modernize(Module, NS, Ref, Range, Opts).
machinery_modernizer_backend:modernize(Module, NS, Id, Range, Opts).

View File

@ -11,7 +11,6 @@
-type namespace() :: machinery:namespace().
-type id() :: machinery:id().
-type ref() :: machinery:ref().
-type range() :: machinery:range().
-type backend_opts() :: machinery:backend_opts(_).
@ -21,6 +20,6 @@
-type backend() :: module().
-spec modernize(backend(), namespace(), ref(), range(), backend_opts()) -> ok | {error, notfound}.
modernize(Backend, Namespace, Ref, Range, Opts) ->
Backend:modernize(Namespace, Ref, Range, Opts).
-spec modernize(backend(), namespace(), id(), range(), backend_opts()) -> ok | {error, notfound}.
modernize(Backend, Namespace, Id, Range, Opts) ->
Backend:modernize(Namespace, Id, Range, Opts).

View File

@ -7,7 +7,7 @@
-include_lib("mg_proto/include/mg_proto_state_processing_thrift.hrl").
-type namespace() :: machinery:namespace().
-type ref() :: machinery:ref().
-type id() :: machinery:id().
-type range() :: machinery:range().
-type logic_handler(T) :: machinery:logic_handler(T).
@ -94,10 +94,10 @@ new(WoodyCtx, Opts = #{client := _, schema := _}) ->
%% Machinery backend
-spec modernize(namespace(), ref(), range(), backend_opts()) -> ok | {error, notfound}.
modernize(NS, Ref, Range, Opts) ->
-spec modernize(namespace(), id(), range(), backend_opts()) -> ok | {error, notfound}.
modernize(NS, Id, Range, Opts) ->
Client = get_client(Opts),
Descriptor = {NS, Ref, Range},
Descriptor = {NS, Id, Range},
case machinery_mg_client:modernize(marshal(descriptor, Descriptor), Client) of
{ok, ok} ->
ok;
@ -139,10 +139,10 @@ marshal_event_content(Schema, Version, Context0, _Event = #{data := EventData0})
get_client(#{client := Client, woody_ctx := WoodyCtx}) ->
machinery_mg_client:new(Client, WoodyCtx).
build_schema_context(NS, Ref) ->
build_schema_context(NS, Id) ->
#{
machine_ns => NS,
machine_ref => Ref
machine_id => Id
}.
%% Marshalling

View File

@ -4,7 +4,7 @@ erlang:
secret_cookie_file: "/opt/machinegun/etc/cookie"
namespaces:
payproc/tags:
example/tags:
processor:
url: http://machinery:8022/v1/stateproc
general:

View File

@ -166,11 +166,11 @@ process_repair(_Args, _Machine, _, _Opts) ->
start(ID, Args, C) ->
machinery:start(namespace(), ID, Args, get_backend(C)).
call(Ref, Args, C) ->
machinery:call(namespace(), Ref, Args, get_backend(C)).
call(ID, Args, C) ->
machinery:call(namespace(), ID, Args, get_backend(C)).
call(Ref, Args, Range, C) ->
machinery:call(namespace(), Ref, Range, Args, get_backend(C)).
call(ID, Args, Range, C) ->
machinery:call(namespace(), ID, Range, Args, get_backend(C)).
namespace() ->
general.

View File

@ -80,17 +80,17 @@ tag_success(C) ->
Tag = genlib:unique(),
ID = pid_to_binary(self()),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts).
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts).
-spec tag_twice_success(config()) -> test_return().
tag_twice_success(C) ->
Tag = genlib:unique(),
ID = pid_to_binary(self()),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts).
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts).
-spec single_tag_set_only(config()) -> test_return().
single_tag_set_only(C) ->
@ -99,7 +99,7 @@ single_tag_set_only(C) ->
IDs = [integer_to_binary(E) || E <- lists:seq(1, 42)],
Rs = genlib_pmap:map(
fun(ID) ->
{ID, machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts)}
{ID, machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts)}
end,
IDs
),
@ -112,9 +112,9 @@ untag_success(C) ->
Tag = genlib:unique(),
ID = pid_to_binary(self()),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID, Opts),
{error, unset} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts).
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID, Opts),
{error, unset} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts).
-spec conflict_untag_failure(config()) -> test_return().
conflict_untag_failure(C) ->
@ -122,32 +122,32 @@ conflict_untag_failure(C) ->
ID1 = pid_to_binary(self()),
ID2 = pid_to_binary(cfg(suite_sup, C)),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID1, Opts),
{error, {set, ID1}} = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID2, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID1, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID2, Opts).
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID1, Opts),
{error, {set, ID1}} = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID2, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID1, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID2, Opts).
-spec reset_tag_success(config()) -> test_return().
reset_tag_success(C) ->
Tag = genlib:unique(),
ID = pid_to_binary(self()),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(payproc, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:tag(payproc, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts).
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:untag(example, Tag, ID, Opts),
ok = machinery_machine_unique_tag_mg_example:tag(example, Tag, ID, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts).
-spec tag_unset_timely(config()) -> test_return().
tag_unset_timely(C) ->
Tag = genlib:unique(),
ID = pid_to_binary(self()),
Opts = #{woody_ctx => get_woody_ctx(C)},
ok = machinery_machine_unique_tag_mg_example:tag_until(payproc, Tag, ID, {timeout, 1}, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts),
ok = machinery_machine_unique_tag_mg_example:tag_until(example, Tag, ID, {timeout, 1}, Opts),
{ok, ID} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts),
% twice as much as needed
ok = timer:sleep(2 * 1000),
{error, unset} = machinery_machine_unique_tag_mg_example:get(payproc, Tag, Opts).
{error, unset} = machinery_machine_unique_tag_mg_example:get(example, Tag, Opts).
%%

View File

@ -161,7 +161,7 @@ get_version(event) ->
-spec process_context(machinery_mg_schema:t(), machinery_mg_schema:context()) ->
machinery_mg_schema:context() | no_return().
process_context(T, C) ->
?assertMatch(#{machine_ref := _, machine_ns := general}, C),
?assertMatch(#{machine_id := _, machine_ns := general}, C),
do_process_context(T, C).
-spec do_process_context(machinery_mg_schema:t(), machinery_mg_schema:context()) ->
@ -188,11 +188,11 @@ do_process_context({aux_state, _}, C) ->
start(ID, Args, C) ->
machinery:start(namespace(), ID, Args, get_backend(C)).
call(Ref, Args, C) ->
machinery:call(namespace(), Ref, Args, get_backend(C)).
call(ID, Args, C) ->
machinery:call(namespace(), ID, Args, get_backend(C)).
repair(Ref, Args, Range, C) ->
machinery:repair(namespace(), Ref, Range, Args, get_backend(C)).
repair(ID, Args, Range, C) ->
machinery:repair(namespace(), ID, Range, Args, get_backend(C)).
namespace() ->
general.

View File

@ -127,7 +127,7 @@ failed_repair_test(C) ->
Reason = fail,
?assertEqual(ok, start(ID, init_numbers, C)),
?assertError({failed, general, ID}, call(ID, fail, C)),
?assertEqual({error, {failed, {Reason, #{machine_ns => general, machine_ref => ID}}}}, repair(ID, Reason, C)),
?assertEqual({error, {failed, {Reason, #{machine_ns => general, machine_id => ID}}}}, repair(ID, Reason, C)),
?assertError({failed, general, ID}, call(ID, get_events, C)).
-spec unexpected_failed_repair_test(config()) -> test_return().
@ -194,14 +194,14 @@ process_repair(unexpected_fail, _Machine, _, _Opts) ->
start(ID, Args, C) ->
machinery:start(namespace(), ID, Args, get_backend(C)).
call(Ref, Args, C) ->
machinery:call(namespace(), Ref, Args, get_backend(C)).
call(ID, Args, C) ->
machinery:call(namespace(), ID, Args, get_backend(C)).
repair(Ref, Args, C) ->
machinery:repair(namespace(), Ref, Args, get_backend(C)).
repair(ID, Args, C) ->
machinery:repair(namespace(), ID, Args, get_backend(C)).
repair(Ref, Args, Range, C) ->
machinery:repair(namespace(), Ref, Range, Args, get_backend(C)).
repair(ID, Args, Range, C) ->
machinery:repair(namespace(), ID, Range, Args, get_backend(C)).
namespace() ->
general.

View File

@ -203,11 +203,11 @@ process_repair(_Args, _Machine, _, _Opts) ->
start(ID, Args, C) ->
machinery:start(namespace(), ID, Args, get_backend(C)).
call(Ref, Args, C) ->
machinery:call(namespace(), Ref, Args, get_backend(C)).
call(ID, Args, C) ->
machinery:call(namespace(), ID, Args, get_backend(C)).
get(Ref, C) ->
machinery:get(namespace(), Ref, get_backend(C)).
get(ID, C) ->
machinery:get(namespace(), ID, get_backend(C)).
namespace() ->
general.