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

use composite buffers where possible #3737

Closed
wants to merge 7 commits into from

Conversation

Outfluencer
Copy link
Collaborator

i think this should reduce memory allocations
I have tested it, its running without any issues for me.
But i did no perfromace tests for now, so they are welcome.

This should reduce memory allocations
@Janmm14
Copy link
Contributor

Janmm14 commented Sep 4, 2024

This should crash for native encryption for packets with size smaller than encryption threshold, as native encryption also requires a singular memory address which a composite bytebuf cannot deliver.

@Outfluencer
Copy link
Collaborator Author

oh you're probably right i tested it on an arm server (custom natives are not supported)

@Janmm14
Copy link
Contributor

Janmm14 commented Sep 5, 2024

The naming of fast boolean in my opinion should be something like canUseComposite.
And your complete removal from the length field prepender creates simplicity, but I think we could have it on fast and then if the CipherEncoder is added, we could set the prepender to's canUseComposite to false if we use natives, same for when adding compress.

ch.addBefore( PipelineUtils.FRAME_PREPENDER, PipelineUtils.ENCRYPT_HANDLER, new CipherEncoder( encrypt ) );

https://github.com/SpigotMC/BungeeCord/blob/master/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java#L172

(i would just leave out the logic to re-enable canUseComposite on compress removal if cipher not present tho)

@Outfluencer
Copy link
Collaborator Author

Outfluencer commented Sep 5, 2024

The naming of fast boolean in my opinion should be something like canUseComposite. And your complete removal from the length field prepender creates simplicity, but I think we could have it on fast and then if the CipherEncoder is added, we could set the prepender to's canUseComposite to false if we use natives, same for when adding compress.

ch.addBefore( PipelineUtils.FRAME_PREPENDER, PipelineUtils.ENCRYPT_HANDLER, new CipherEncoder( encrypt ) );

https://github.com/SpigotMC/BungeeCord/blob/master/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java#L172
(i would just leave out the logic to re-enable canUseComposite on compress removal if cipher not present tho)

sounds logic and simple, i will change it.

@Outfluencer
Copy link
Collaborator Author

Outfluencer commented Sep 5, 2024

(i would just leave out the logic to re-enable canUseComposite on compress removal if cipher not present tho)

why isn't it simple to just set useComposite to true again?

@Outfluencer
Copy link
Collaborator Author

The naming of fast boolean in my opinion should be something like canUseComposite. And your complete removal from the length field prepender creates simplicity, but I think we could have it on fast and then if the CipherEncoder is added, we could set the prepender to's canUseComposite to false if we use natives, same for when adding compress.

The prepender is an instance (its shared), should we create a new one per connection, or should we add another class and switch them in the pipeline. I prefer per channel Varint21LengthFieldPrepender

@Janmm14
Copy link
Contributor

Janmm14 commented Sep 5, 2024

The naming of fast boolean in my opinion should be something like canUseComposite. And your complete removal from the length field prepender creates simplicity, but I think we could have it on fast and then if the CipherEncoder is added, we could set the prepender to's canUseComposite to false if we use natives, same for when adding compress.

The prepender is an instance (its shared), should we create a new one per connection, or should we add another class and switch them in the pipeline. I prefer per channel Varint21LengthFieldPrepender

Yeah I would un-share it (change to per-connection) instead of replacing the impl.

(i would just leave out the logic to re-enable canUseComposite on compress removal if cipher not present tho)

why isn't it simple to just set useComposite to true again?

I thought that, as the minecraft protocol does not support this and when it was supported it could cause problems due to missing acknowledgement packet (as the threshold applies both ways), we could just not care about this potential performance penalty when compression is removed.

@Outfluencer
Copy link
Collaborator Author

Outfluencer commented Sep 5, 2024

I don't think that it could break anything. As there are no raceconditions because evey operation is performed on the same thread right? (its not possible that somehow this boolean is changed while a packet write or read in the pipeline is processed)
It can only change the encoder behaviour of the next packet sent

But i will test what happens if i change the compression multiple times

@Janmm14
Copy link
Contributor

Janmm14 commented Sep 5, 2024

The naming of fast boolean in my opinion should be something like canUseComposite. And your complete removal from the length field prepender creates simplicity, but I think we could have it on fast and then if the CipherEncoder is added, we could set the prepender to's canUseComposite to false if we use natives, same for when adding compress.

The prepender is an instance (its shared), should we create a new one per connection, or should we add another class and switch them in the pipeline. I prefer per channel Varint21LengthFieldPrepender

Oh yeah then the prepender should be per-channel.

(i would just leave out the logic to re-enable canUseComposite on compress removal if cipher not present tho)

why isn't it simple to just set useComposite to true again?

Well its possible, doesn't care, but as its a code path that's essentially unused

@Janmm14
Copy link
Contributor

Janmm14 commented Sep 6, 2024

purely codewise looks good to me now!

@md-5 md-5 self-assigned this Sep 8, 2024
{
ByteBuf buf = ctx.alloc().directBuffer( headerLen );
DefinedPacket.writeVarInt( bodyLen, buf );
list.add( ctx.alloc().compositeBuffer( 2 ).addComponents( true, buf, msg.retain() ) );
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason why this isn't a direct composite but the compressor is?

Copy link
Collaborator Author

@Outfluencer Outfluencer Sep 8, 2024

Choose a reason for hiding this comment

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

By default it should use direct in the impl but i can just call directCompositeBuffer method.
I will change it

@andrewkm
Copy link

andrewkm commented Sep 12, 2024

@md-5 this commit is causing all sorts of issues with various plugins, as has been reported to me by a few other server owners, not to mention it broke floodgate as well, thus I can't even properly test myself.

@md-5
Copy link
Member

md-5 commented Sep 12, 2024

If it's a plugin not using the API then it's not really a bungee issue. Given that networking isn't exposed to plugins this is almost certainly the case.

@Outfluencer
Copy link
Collaborator Author

@md-5 this commit is causing all sorts of issues with various plugins, as has been reported to me by a few other server owners, not to mention it broke floodgate as well, thus I can't even properly test myself.

Floodgate accessed a private static final field that does not exist anymore.

@Outfluencer
Copy link
Collaborator Author

@andrewkm i fixed the floodgate issue

@andrewkm
Copy link

@andrewkm i fixed the floodgate issue

Thank you! :)

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.

4 participants