2

onewayThrift 関数定義の 1 つで修飾子を使用しています。

...
oneway void secret_function(1: string x, 2: string y),
...

Thrift を介してそれぞれの Erlang コードを生成すると、これは次のように変換されます。

...
function_info('secret_function', reply_type) ->
  oneway_void;
function_info('secret_function', exceptions) ->
  {struct, []};
...

oneway_voidそこのアトムに注目してください。

関数が実行されると、secret_function次のエラーが発生します。

=ERROR REPORT==== 2-Sep-2010::18:17:08 ===
oneway void secret_function threw error which must be ignored: {error,
                                                             function_clause,
                                                             [{thrift_protocol,
                                                               term_to_typeid,
                                                               [oneway_void]},
                                                              {thrift_protocol,
                                                               struct_write_loop,
                                                               3},
                                                              {thrift_protocol,
                                                               write,2},
                                                              {thrift_processor,
                                                               send_reply,
                                                               4},
                                                              {thrift_processor,
                                                               handle_function,
                                                               2},
                                                              {thrift_processor,
                                                               loop,1}]}

ユーザー コードに含まれる可能性のあるバグとは別に、ここではthrift_protocol:term_to_typeid/1関数がアトムを引数として呼び出されoneway_void、関数句が発生します。実際、コード (thrift_protocol.erl) から読み取ると、次のようになります。

...
term_to_typeid(void) -> ?tType_VOID;
term_to_typeid(bool) -> ?tType_BOOL;
term_to_typeid(byte) -> ?tType_BYTE;
term_to_typeid(double) -> ?tType_DOUBLE;
term_to_typeid(i16) -> ?tType_I16;
term_to_typeid(i32) -> ?tType_I32;
term_to_typeid(i64) -> ?tType_I64;
term_to_typeid(string) -> ?tType_STRING;
term_to_typeid({struct, _}) -> ?tType_STRUCT;
term_to_typeid({map, _, _}) -> ?tType_MAP;
term_to_typeid({set, _}) -> ?tType_SET;
term_to_typeid({list, _}) -> ?tType_LIST.
...

バグ?他の説明はありますか?なぜoneway_voidその関数に渡されているのですか?

4

1 に答える 1

0

舞台裏で何が起こっているか知っていると思います。

私の Erlang コード (the secret_function/2) は、単に ok ではなく {ok, pid()} を返していました。function を宣言したので、これが概念的に間違っていoneway_voidたとしても、問題の原因を特定するのに時間がかかりました。hがすでに行ってhandle_succesいるのと同じように動作するように、Thriftの関数を調整できるかもしれません。現時点でandle_function_catchの外観は次のとおりです。handle_function_catch

...
case {ErrType, ErrData} of
    _ when IsOneway ->
        Stack = erlang:get_stacktrace(),
        error_logger:warning_msg(
          "oneway void ~p threw error which must be ignored: ~p",
          [Function, {ErrType, ErrData, Stack}]),
        {State, ok};
...

関数が として宣言されていてもoneway_void、例外が発生すると、問題が報告されます。同じ理由によると、潜在的な新しい handle_success 関数は次のようになります。

handle_success(State = #thrift_processor{service = Service},
               Function,
               Result) ->
    ReplyType  = Service:function_info(Function, reply_type),
    StructName = atom_to_list(Function) ++ "_result",

    case Result of
        {reply, ReplyData} when ReplyType =:= oneway_void ->
            Stack = erlang:get_stacktrace(),
            error_logger:warning_msg(
              "oneway void ~p sent reply which must be ignored: ~p",
              [Function, {ReplyData, Stack}]),
            {State, ok};
                {reply, ReplyData} ->
            Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}},
            send_reply(State, Function, ?tMessageType_REPLY, Reply);

        ok when ReplyType == {struct, []} ->
            send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}});

        ok when ReplyType == oneway_void ->
            %% no reply for oneway void
            {State, ok}
    end.

ここでは、関数が次のように定義されているかどうかを確認しているだけでoneway_void、これが true であり、atom とは異なる戻り値を受け取る場合は、戻りok値を無視して事故を報告します。

これは、開発者が更新されたhandle_success関数で見るものです:

=ERROR REPORT==== 7-Sep-2010::11:06:43 ===
oneway void secret_function sent reply which must be ignored: {{ok,
                                                                  <0.262.0>},
                                                                 []}

そして、それはあなたの命を少なくとも一度は救うことができます(引用).

于 2010-09-07T10:17:19.087 に答える