-
Notifications
You must be signed in to change notification settings - Fork 28
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
feat: Make models Sendable #829
base: main
Are you sure you want to change the base?
Conversation
defer { lock.unlock() } | ||
_wrappedValue = newValue | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This property wrapper is mostly same as before, but now stores its value in private storage that is protected by a lock when getting & setting.
Since it enforces exclusive access to its wrapped value, it can now be Sendable
.
@@ -8,7 +8,7 @@ | |||
import class Foundation.FileHandle | |||
import struct Foundation.Data | |||
|
|||
public enum ByteStream { | |||
public enum ByteStream: Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conformance is possible since Stream
has been made Sendable
in this PR.
@@ -8,8 +8,9 @@ | |||
import struct Foundation.Data | |||
import struct Foundation.Date | |||
|
|||
public protocol SmithyDocument { | |||
public protocol SmithyDocument: Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the SmithyDocument
implementations are now sendable without any code change, since they only store data that is either immutable and/or Sendable
.
public class ChunkedStream { | ||
private var inputStream: Stream | ||
public class ChunkedStream: @unchecked Sendable { | ||
private let inputStream: Stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Streams were designed to be thread-safe so they may be marked @unchecked Sendable
so long as we maintain that thread safety.
@@ -15,11 +15,3 @@ public enum EventStreamError: Error { | |||
/// This may be due to missing required headers | |||
case invalidMessage(String) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extension below was unused and causing compiler warnings, so it was deleted.
@@ -26,7 +26,7 @@ public final class FileStream: Stream { | |||
let fileHandle: FileHandle | |||
|
|||
/// Returns the current position of the stream. | |||
public var position: Data.Index | |||
public private(set) var position: Data.Index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically this is a breaking API change but it would cause a bug to alter this property from outside this type.
@@ -39,7 +39,7 @@ class EnumGeneratorTests { | |||
|
|||
val expectedGeneratedEnum = """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below changes are Kotlin codegen tests. Changes in test expectations:
- All generated structs, unions, enums, & intEnums are Sendable.
- Whitespace around type declarations is made uniform, with an empty line before a declaration & none after.
- Test strings are left-justified to allow for easy maintenance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try turning off whitespace changes on the Github diff to see the more substantial part of the test changes.
@@ -5,7 +5,7 @@ | |||
// SPDX-License-Identifier: Apache-2.0 | |||
// | |||
|
|||
public struct Headers { | |||
public struct Headers: Sendable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Headers
and Header
may be marked Sendable
without any further change since they are struct
s that only store value types.
"}", | ||
SwiftTypes.Protocols.Sendable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark generated enum
s with Sendable
.
"}", | ||
SwiftTypes.Protocols.Sendable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark generated intEnum
s with Sendable
.
Also adjust spacing a bit.
val equatableConformance = writer.format(": \$N ", SwiftTypes.Protocols.Equatable).takeIf { shape.hasTrait<EquatableConformanceTrait>() } ?: "" | ||
writer.openBlock("public struct \$struct.name:L $equatableConformance{") | ||
val equatableConformance = writer.format(", \$N", SwiftTypes.Protocols.Equatable).takeIf { shape.hasTrait<EquatableConformanceTrait>() } ?: "" | ||
writer.openBlock("public struct \$struct.name:L: \$N$equatableConformance {", SwiftTypes.Protocols.Sendable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark generated struct
s with Sendable
.
Also adjust spacing of generated code.
val equatableConformance = (": " + SwiftTypes.Protocols.Equatable + " ").takeIf { shape.hasTrait<EquatableConformanceTrait>() } ?: "" | ||
writer.openBlock("public ${indirectOrNot}enum \$union.name:L $equatableConformance{", "}\n") { | ||
val equatableConformance = writer.format(", \$N", SwiftTypes.Protocols.Equatable).takeIf { shape.hasTrait<EquatableConformanceTrait>() } ?: "" | ||
writer.openBlock("public ${indirectOrNot}enum \$union.name:L: \$N$equatableConformance {", "}", SwiftTypes.Protocols.Sendable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mark generated union
s with Sendable
.
Also adjust formatting.
@@ -31,6 +31,7 @@ object SwiftTypes { | |||
val RawRepresentable = builtInSymbol("RawRepresentable", SwiftDeclaration.PROTOCOL) | |||
val CaseIterable = builtInSymbol("CaseIterable", SwiftDeclaration.PROTOCOL) | |||
val CustomDebugStringConvertible = builtInSymbol("CustomDebugStringConvertible", SwiftDeclaration.PROTOCOL) | |||
val Sendable = builtInSymbol("Sendable", SwiftDeclaration.PROTOCOL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SwiftSymbol
for the Sendable
protocol.
Issue #
awslabs/aws-sdk-swift#1768
Description of changes
Generated models are now
Sendable
. Generated structures, unions, enums, and intEnums all declareSendable
conformance in their definitions. Changes needed to enable this conformance:SmithyDocument
protocol now conforms toSendable
. All of our document implementation types are fullySendable
without modification because their properties are already either immutable orSendable
.ByteStream
enumeration is nowSendable
. To support this:ReadableStream
andWriteableStream
protocols both now conform toSendable
.Sendable
or@unchecked Sendable
. Streams were built to be thread-safe so this merely requires us to manually maintain that thread safety on stream types going forward.@Indirect
property wrapper (used for enabling recursive structures) is provided with@unchecked Sendable
conformance that uses a lock to enforce exclusive access to its wrapped value.Header
andHeaders
properties are madeSendable
with no changes to implementation.Also:
CRTError
andAsyncThrowingStream
that were unused and causing compiler warnings.Scope
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.