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

coding-style: propose documentation recommendations #16400

Merged
merged 3 commits into from
Feb 7, 2024

Conversation

rockwotj
Copy link
Contributor

@rockwotj rockwotj commented Jan 31, 2024

In an effort to prioritize documentation, add expectations to the coding guide on what should
be documented.

As an example of existing codebase that I think is fairly well documented is CockroachDB:

They have "package" level documentation (which we'll solve with README):
https://github.com/cockroachdb/cockroach/blob/b876c990bbd40af075dda6ab6b28b392ec6da19f/pkg/gossip/doc.go#L12-L15

If you look through the entry point to that exact package, I think it's pretty solid:
https://github.com/cockroachdb/cockroach/blob/master/pkg/gossip/gossip.go

Other package examples from CockroachDB:

As for our own codebase, I think we have parts that are well documented, and places that could use some love. I believe the largest gap at the moment is some "per library documentation" to give an overview of the lay of the land and high level responsibility of a library. I think another thing that can help reduce the surface area of libraries and make them easier to understand is breaking them. For example, the cluster library does so much that it's hard to imagine writing a good README.md there.

Good examples

class state_machine_manager final {

class segment_appender {


class batch_cache {

class cache {

Examples that could use some documentation love

class controller {

class group_stm {

class connection_cache final

class base_manifest {

class topics_frontend {

class config_frontend final {

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v23.3.x
  • v23.2.x
  • v23.1.x

Release Notes

  • none

Copy link
Contributor

@michael-redpanda michael-redpanda left a comment

Choose a reason for hiding this comment

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

love it

Comment on lines 9 to 10
Public header files should go in an `includes` directory within the module they belong to.
For example, a module named `foo` should have public header files within `src/v/foo/include/foo`.
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for this.

Should the include directory end up in target_include_directories(<target> PUBLIC include) so only a subset of headers are exposed from the module?

Would be nice that only some of the headers are actually exposed, rather than our current methodology of putting src/v in include_directory (

include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
)?

Copy link
Contributor Author

@rockwotj rockwotj Jan 31, 2024

Choose a reason for hiding this comment

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

Noah already has setup the work for this: c9a2dbc

Eventually we can remove the root include, and yes we're working towards having private vs public headers and helping our build system and dependency graph be cleaner.

dotnwat
dotnwat previously approved these changes Jan 31, 2024
@@ -6,12 +6,50 @@ The document covers style and convention not enforced by clang-format.

Header files have the `.h` extension, source files use the `.cc` extension.

Public header files should go in an `includes` directory within the module they belong to.
For example, a module named `foo` should have public header files within `src/v/foo/include/foo`.
Copy link
Member

Choose a reason for hiding this comment

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

👍

Comment on lines 50 to 51
or other common lifecycle methods like `start` and `stop` could be considered trivial. It's highly
recommended to error on the side of verbosity when documenting functions however.
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we can find (1) some article about how to write good function documentation and (2) a code base with good examples. Sometimes I catch myself writing prose that matches 1-1 with the code, but I suspect that isn't really the type of doc string we're looking for.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. Let me look around a bit and get back to this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think cockroach is a decent example.

They have "package" level documentation (which we'll solve with README): https://github.com/cockroachdb/cockroach/blob/master/pkg/gossip/doc.go

If you look through the entry point to that exact package, I think it's pretty solid:
https://github.com/cockroachdb/cockroach/blob/master/pkg/gossip/gossip.go

Another package example from cockroach:
https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/doc.go, or https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/sqlstats/ssprovider.go

Anyways, I don't think more text is better, but something is better than nothing. Maybe it's better to surface stuff in our codebase?

Example of something good IMO:

class state_machine_manager final {

Example of something that could be better IMO:

class controller {

Copy link
Member

Choose a reason for hiding this comment

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

This looks great to me!

mmaslankaprv
mmaslankaprv previously approved these changes Feb 6, 2024
@mmaslankaprv
Copy link
Member

this is great

src/v/coding-style.md Outdated Show resolved Hide resolved
@@ -6,12 +6,50 @@ The document covers style and convention not enforced by clang-format.

Header files have the `.h` extension, source files use the `.cc` extension.

Public header files should go in an `includes` directory within the module they belong to.
Copy link
Member

Choose a reason for hiding this comment

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

This may need some clarification of what "public" means here. Is "public" is entirely concerned with whether other redpanda modules #include them directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Will clarify with:

Public header files (files that are allowed to be #included by other modules).


### Modules

Modules themselves should have a `README.md` file explaining the purpose of the module,
Copy link
Member

Choose a reason for hiding this comment

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

What is a module here? A module is a top-level directory in src/v?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any CMake library target that isn't a test - generally this is one to one with a directory, but increasingly these are not all top-level directories.

Open to better naming because of the confusion with C++ modules.

Copy link
Member

Choose a reason for hiding this comment

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

Open to better naming because of the confusion with C++ modules.

I think module is fine but we should probably have one sentence briefly introducing what a module is, to us, before the point we start using that term.

src/v/coding-style.md Outdated Show resolved Hide resolved
src/v/coding-style.md Outdated Show resolved Hide resolved
* Which cores it exists on (if a sharded service)
* If it is a cluster/node/shard view of information

While only required in public headers, it's also encouraged to add this information to key classes
Copy link
Member

Choose a reason for hiding this comment

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

Personally I think we should document all classes. Ultimately I feel the "module boundary" is not a very important one here, inside Redpanda, for the purposes of documentation because in general core is working across modules, i.e., it is not as if the public header documentation is consumed by a different set of people. The same reasoning for documenting "public" headers mostly applies to classes anywhere else?

Copy link
Contributor Author

@rockwotj rockwotj Feb 6, 2024

Choose a reason for hiding this comment

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

That's fair - again I was trying to find a minimum subset of agreeable points to start this, but I can circle around with various TLs and get everyone's thoughts.

travisdowns
travisdowns previously approved these changes Feb 6, 2024
Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
@rockwotj
Copy link
Contributor Author

rockwotj commented Feb 6, 2024

Updates: Took a stronger stance on documentation and added examples to the cover letter.

@piyushredpanda piyushredpanda changed the title coding-style: propose documentation recommentations coding-style: propose documentation recommendations Feb 6, 2024
@dotnwat
Copy link
Member

dotnwat commented Feb 6, 2024

@travisdowns's updates in storage segment appender have really good comments IIRC

@vbotbuildovich
Copy link
Collaborator

new failures in https://buildkite.com/redpanda/redpanda/builds/44756#018d7f28-ed4c-42a6-9d99-875ff07e5248:

"rptest.tests.recovery_mode_test.RecoveryModeTest.test_recovery_mode"

@vbotbuildovich
Copy link
Collaborator

vbotbuildovich commented Feb 6, 2024

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
The libraries list was out of date, update it to the latest and
greatest.

Signed-off-by: Tyler Rockwood <rockwood@redpanda.com>
@rockwotj
Copy link
Contributor Author

rockwotj commented Feb 6, 2024

Updates:

  • Stronger requirements for documenting structs
  • Add examples from our code base to cover letter
  • update subsystem list and descriptions
  • Add docs guidelines and a couple of posts that might be helpful on writing comments

Copy link
Member

@travisdowns travisdowns left a comment

Choose a reason for hiding this comment

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

Looks great.

@dotnwat dotnwat merged commit 44f9cbc into redpanda-data:dev Feb 7, 2024
16 checks passed
@rockwotj rockwotj deleted the docs branch February 7, 2024 19:26

For the curious, here are some useful articles on this subject:

* [Coding Horror - Code tells you how, comments tell you why](https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

### Functions

Non trivial free and class functions should be documented. Trivial is ultimately
a judgement call, but a rule of thumb is that getter methods (like `iobuf value() const { return _value; }`)
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally these would have internally enforced invariants. However, sometimes even a trivial method like that needs documentation about preconditions. E.g. that start() must have been called before.

An assert inside might serve as documentation too. If the method declaration is split from definition then I'd vote for stating the invariants in the declaration (in header file) too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Totally agree. Happy to take a look at a PR if you want to update this section. I'm not discouraging comments here, but trying to prevent someone feeling burdened to write a useless comment like:

/**
 * Get the value.
 */
iobuf value() const { return _value; }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants