Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add *Record ProtoBuf messages and corresponding serde functions. #2831

Merged
merged 16 commits into from
Jan 22, 2024

Conversation

panh99
Copy link
Contributor

@panh99 panh99 commented Jan 19, 2024

  • Defined 6 new messages in a new file recordset.proto
  • Wrote serde functions for the new messages
  • Added unittests accordingly.
  • Updated the test_proto_file_count (b/c we now have 6 proto files)

src/proto/flwr/proto/recordset.proto Show resolved Hide resolved
repeated Array data_values = 2;
}

message MetricsRecord { map<string, Value> data = 1; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MetricsRecord only allows int and float types (and lists of those two types)

Copy link
Contributor Author

@panh99 panh99 Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I get it.
I was thinking that, since we enforce type checks when instantiating the MetricsRecord, which means the data field inside must be valid, we can reuse Value to store them to avoid having repetitive code in proto files and in serde.py. But I also happy with copy-pasting part of the serde functions for Value and create new messages for MetricsRecordValue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, makes sense. I suspected that to be the case :)

My recommendation would be to create new messages that map closely to the Python code for two reasons:

  1. Enable us to remove Value once we migrated everything to RecordSet
  2. Make it easier to implement non-Python clients based on the ProtoBuf definitions


message MetricsRecord { map<string, Value> data = 1; }

message ConfigsRecord { map<string, Value> data = 1; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigsRecord doesn't allow bool yet. That's sth we should fix in a separate PR by adding it to ConfigsRecord.

The more general question: should we define ProtoBuf messages that follow the same naming scheme as their Python dataclass counterpart?

Copy link
Contributor Author

@panh99 panh99 Jan 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for reusing Value instead of creating a new message ConfigsRecordValue is the same as above (MetricsRecord).

Re: naming. IMO, we should use different names or even store them in a different way in a TaskIns. There's no benefits to keep them strictly equivalent. I think the ProtoBuf messages is aimed solely to transfer contents over the wire, which is different from the purpose of introducing record types. And hence I think we don't need to follow the same naming scheme and even don't need to have a counterpart for each dataclass record.

The advantage of not having counterparts is that we may not have to change protobuf messages and serde functions accordingly when we decide to modify our RecordSet. The disadvantage is that it's not easy to design a protobuf messages for general uses, and the naming will be less intuitive if we allow users to change protobuf messages in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we do not need to aim for a strict 1:1 mapping from Python to ProtoBuf.

I do think however that there is an advantage to keeping them close. As stated in the other comment, we want to implement Flower clients in languages other than Python. This usually starts with compiling existing ProtoBuf messages. If those messages are close to the Python level, it will be easier for others to implement the Java/C++/... counterpart.

In addition to that, it will maintenance of the Python client easier as well. In the case of MetricsRecord, for example, we would not need to check for unsupported Value types if we have a MetricsRecord on the ProtoBuf level that supports the exact set of types that the Python MetricsRecord supports.

@danieljanes danieljanes enabled auto-merge (squash) January 22, 2024 17:38
@danieljanes danieljanes merged commit d7be8fb into main Jan 22, 2024
29 checks passed
@danieljanes danieljanes deleted the records branch January 22, 2024 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants