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

multi: Make NewMessage() usable for creating messages for reading #591

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

matheusd
Copy link
Contributor

@matheusd matheusd commented Aug 30, 2024

This PR modifies Reset() (and consequently NewMessage()) so that it can be used to initialize messages for reading.

Before this PR, Reset() would enforce that space for the root pointer was allocated in the associated arena, which could not be done for read-only messages. This PR changes it so that space for the root pointer is only allocated when strictly necessary.

In the future, this will allow protecting Message values from wrong usage by enforcing the use of NewMessage to initialize message objects (instead of use of zero valued messages).

Warning

This is a breaking API change. NewMessage() would fail if the underlying arena could not allocate space, and if this PR is merged that will not be true anymore.

This commit changes all occurrences of
NewMessage(NewSingleSegmentArena(nil)) to NewSingleSegmentArena(nil) and
all occurrences of NewMessage(NewMultiSegmentArena(nil)) to
NewMultiSegmentArena(nil).

Also, occurrences of Message{Arena: XXX} (where XXX is either a single
or multi segment arena) are changed when possible as well.

In the future, this will allow protecting Message values from wrong
usage by enforcing the use of NewMessage to initialize message objects
(instead of use of zero valued messages).
The passed slice cannot be guaranteed to be from the pool, therefore it
should not be returned there during Release.
@matheusd matheusd marked this pull request as draft August 30, 2024 20:04
Previously, NewMessage() would always attempt to allocate the first
word of the first segment and would consider arenas with more than 1
segment as not usable.

This restriction is lifted in this commit by only attempting to allocate
the first segment and not the root pointer space. This allows passing a
fully populated Arena object to Reset(), which in turns allows passing
it to NewMessage.

This will be helpful by ensuring NewMessage can be used in all
situations where a message is needed (not just for writing).

NOTE: this is a breaking API change. Before this commit, NewMessage
would fail for read-only arenas or that otherwise could not allocate
space for the root pointer.

The allocation for the root pointer space is now enforced only when
(1) performing an initial allocation or (2) setting the root pointer.

Enforcement on (2) is only necessary because one call path in file
fileparts.go makes a call to SetRoot before attempting to allocate space
in the message. This is likely an erroneous call and should be
investigated in the future in order to simplify the code.
This changes all ocurrences of message instantiation to use
NewMessage().

This unifies all code for message init under a single code path.

In the future, it may be possible to make all message fields unexported
in order to better enforce message invariants.
@matheusd matheusd changed the title multi: Use NewXXXMessage(nil) where possible multi: Make NewMessage() usable for creating messages for reading Sep 12, 2024
@matheusd matheusd marked this pull request as ready for review September 12, 2024 18:22
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.

1 participant