代码之家  ›  专栏  ›  技术社区  ›  Roberto Aloi

在节俭函数定义中使用“单向空”

  •  2
  • Roberto Aloi  · 技术社区  · 14 年前

    我用的是 oneway

    ...
    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}]}
    

    独立于用户代码中可能包含的bug,这里 thrift_protocol:term_to_typeid/1 正在使用调用函数 单向无效

    ...
    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.
    ...
    

    单向无效 传递给那个函数?

    1 回复  |  直到 14 年前
        1
  •  0
  •   Roberto Aloi    14 年前

    我想我知道幕后发生了什么。

    我的Erlang代码 secret_function/2 )返回{ok,pid()}而不是简单的ok。 oneway_void ,我花了一段时间才找出问题的原因。 也许我们可以调整一下 handle_succes 在节俭中起作用,使它的行为与h一样 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};
    ...
    

    ,当引发异常时,将报告问题。根据相同的推理,一个潜在的新handle\u 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.
    

    这里我只是检查函数是否定义为 单向无效 如果这是真的,我仍然收到一个不同于原子的返回值 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>},
                                                                     []}
    

    这至少能救你一次命(同上)。