Почему gRP C Python не видит первое поле? - PullRequest
0 голосов
/ 05 мая 2020

Python gRP C сообщение не сериализует первое поле. Я много раз обновлял protos и все чистил, но это не исправлено. Вы можете видеть журналы, settings_dict имеет поле stop, но после передачи этих полей в AgentSetting оно не отображается в журналах и на стороне сервера. Также я пытался передать поле stop вручную, но его тоже не видно. Раздражает то, что gRP C не генерирует никаких исключений, он принимает поле stop, но не отправляет на сервер, также он не отображается в AgentSetting при печати, но поле stop доступно, как agent_setting.stop.

Это мой прото-файл:

syntax = 'proto3';

import "base.proto";

message ConnectionCheckRequest {
  string host_name = 1;
}

message RecordChunkRequest {
  string host_name = 1;
  string name = 2;
  bytes chunk = 3;
  uint32 chunk_index = 4;
  uint32 chunk_number = 5;
}

message AgentSetting {
    bool stop = 1;

    bool connection = 2;
    bool registered = 3;

    string image_mode = 4;

    uint32 sending_fail_limit = 5;
    uint64 limit_of_old_records = 6;

    string offline_records_exceed_policy = 7;
}

message AgentSettingRequest {
    AgentSetting agent_setting = 1;
    string host_name = 2;
}

message AgentSettingResponse {
    AgentSetting agent_setting = 1;
}

message AgentRegistryRequest {
    AgentSetting agent_setting = 1;
    string host_name = 2;
}

service Chief {
  rpc agent_update_setting(AgentSettingRequest) returns (AgentSettingResponse) {};
  rpc agent_registry(AgentRegistryRequest) returns (Response) {};
  rpc send (stream RecordChunkRequest) returns (Response) {};
  rpc connection_check (ConnectionCheckRequest) returns (Response) {};
}

Это мой фрагмент кода:

def register():
    try:
        with insecure_channel(settings.server_address) as channel:
            setting_dict = settings.dict()

            logger.info(f'\nSetting Dict: {setting_dict}')

            agent_setting = AgentSetting(**setting_dict)

            logger.info(f'\nAgent Setting Instance: \n{agent_setting}')

            response = ChiefStub(channel).agent_registry(
                AgentRegistryRequest(
                    agent_setting=agent_setting,
                    host_name=settings.host_name
                )
            )
            return response
    except Exception as e:
        logger.exception(f'Register Error: {str(e)}')
        return Response(success=False, message="failure")

Журналы:

|2020-05-05T18:33:56.931140+0300| |5480| |INFO| |reqs:register:28| 
Setting Dict: {'stop': False, 'connection': True, 'registered': False, 'image_mode': 'RGB', 'sending_fail_limit': 3, 'limit_of_old_records': 5368709120, 'offline_records_exceed_policy': 'OVERWRITE'}
|2020-05-05T18:33:56.932137+0300| |5480| |INFO| |reqs:register:32| 
Agent Setting Instance: 
connection: true
image_mode: "RGB"
sending_fail_limit: 3
limit_of_old_records: 5368709120
offline_records_exceed_policy: "OVERWRITE"

1 Ответ

0 голосов
/ 05 мая 2020

В proto3 неустановленное значение и значение по умолчанию считаются эквивалентными.

Таким образом, stop: false считается эквивалентом полного исключения stop.

См. Language Guide ( proto3)

Обратите внимание, что для скалярных полей сообщения после анализа сообщения невозможно определить, было ли поле явно установлено на значение по умолчанию (например, было ли установлено логическое значение false) или просто не задано вовсе: вы должны иметь это в виду при определении типов сообщений. Например, не используйте логическое значение, которое включает какое-либо поведение, если установлено значение false, если вы не хотите, чтобы это поведение также происходило по умолчанию. Также обратите внимание, что если для поля скалярного сообщения установлено значение по умолчанию, значение не будет сериализовано в сети.

Обратите внимание, что это отличается от proto2.

...