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

Enforce Sendability #204

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Enforce Sendability #204

wants to merge 1 commit into from

Conversation

gjcairo
Copy link

@gjcairo gjcairo commented Aug 11, 2023

This PR fixes Sendability warnings present when enabling strict concurrency checking.

Motivation:

We want to make sure swift-nio-extras is free of concurrency bugs, and thus removing Sendability warnings is crucial.

Modifications:

Some types have been made Sendable, and in other places either patterns have been changed to ensure we're not crossing concurrency domains, or values have been wrapped with NIOLoopBound when we know we're on a specific EL.

Result:

No more warnings in swift-nio-extras.

public class NIOPCAPRingBuffer {
private var pcapFragments: CircularBuffer<ByteBuffer>
private var pcapCurrentBytes: Int
public final class NIOPCAPRingBuffer: Sendable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this change necessary? The type wasn't thread-safe before, which suggests it was bound to a specific isolation context.

Copy link
Author

Choose a reason for hiding this comment

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

This is a good question. This class is only used in tests by us (although it's public API).

I was trying to get rid of a warning where a NIOPCAPRingBuffer is captured in an ELF/map chained after a call to write on ChannelHandlerContext (the test in question is in TriggerOnCumulativeSizeHandler/TriggerOnCumulativeSizeHandler/write):

let boundedSink = NIOLoopBound(self.sink, eventLoop: context.eventLoop)
context.write(data).map { [pcapRingBuffer] in
  boundedSink.value(captureBytes(ringBuffer: pcapRingBuffer))
}.cascade(to: promise)

This piece of code also seems like a somewhat sensible pattern to do as a client when you're trying to debug something (which is why this class exists as public API, I assume). I'm not sure how to refactor this to get rid of the warning without making the class Sendable, as pcapRingBuffer is modified as a result of the call to context.write(). This means I can't call captureBytes(ringBuffer:) outside of the closure, as we'd trigger the PCAP at the wrong time (causing the wrong behaviour and assertion failures).

I'm open to refactor suggestions if we want to avoid making this Sendable. Having said that, is there any reason why you would suggest avoiding it, Cory? Or would we be better off making these changes?

Comment on lines +27 to +29
private let pcapLock = NIOLock()
private var pcapFragments: CircularBuffer<ByteBuffer>
private var pcapCurrentBytes: Int
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than using a lock should we create a State struct and stick that in a locked-value-box?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that would be better

@@ -39,122 +39,135 @@ internal struct NFS3FileSystemInvoker<FS: NFS3FileSystemNoAuth, Sink: NFS3FileSy
case .mountNull:
self.sink.sendSuccessfulReply(.mountNull, call: callMessage)
case .mount(let call):
let boundedSink = NIOLoopBound(self.sink, eventLoop: self.eventLoop)
Copy link
Contributor

Choose a reason for hiding this comment

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

What guarantees that we're on the correct event-loop here?

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