Skip to content

Commit c20f969

Browse files
Introduce process for increasing protocol version
We need to start using protocol version 6 as it introduces new LiveObjects functionality. The main problem to solve is: how do we make sure that ably-cocoa doesn't force a protocol version on a plugin that can't handle that version? Here we propose a simple solution. It's a bit clunky, but to be honest our whole plugin mechanism is a bit clunky so I think we can live with this additional clunkiness. One other problem of the solution given here — that is, doing major plugin-api releases — is that if, in the future, we have further plugins, then we'll have to do new releases of _all_ the plugins just because we needed to bump plugin-support for one of them. I hope that by the time we need to do further plugins we'll have moved to ably-swift (with plugins in-repo) and we won't have to worry about this! Resolves ably/ably-liveobjects-swift-plugin#107. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dd11843 commit c20f969

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,89 @@ Further documentation will be added in the future.
1010
## Conventions
1111

1212
- Methods whose names begin with `nosync_` must always be called on the client's internal queue.
13+
14+
## Dependency setup
15+
16+
The intention is that:
17+
18+
- ably-cocoa's `Package.swift` declares a dependency on plugin-api
19+
- each plugin's `Package.swift` declares a dependency on plugin-api
20+
- each plugin's `Package.swift` also declares a direct dependency on ably-cocoa
21+
22+
This means that:
23+
24+
- a given version of the plugin is able to specify a _minimum_ version of ably-cocoa
25+
- a given version of ably-cocoa is expected to work with all plugin versions whose minimum it satisfies — i.e. ably-cocoa is _not_ able to specify a minimum version of a plugin
26+
27+
The only way that ably-cocoa can exclude certain plugin versions is by creating a clash in the plugin-api dependency; we avoid using this mechanism where possible as it can cause confusing dependency resolution error messages for users, but reserve it, for example, when [introducing breaking Realtime protocol changes](#breaking-realtime-protocol-version-changes).
28+
29+
## Playbook for making changes
30+
31+
This section describes how to make some common changes that require changes to all three repositories (ably-cocoa, the plugin, and this repo).
32+
33+
### Breaking Realtime protocol version changes
34+
35+
In this section we describe how to make changes that require incrementing the [CSV2](https://sdk.ably.com/builds/ably/specification/main/features/#CSV2) protocol version number.
36+
37+
The key outcome that we wish to achieve is the following:
38+
39+
- a given version of ably-cocoa only needs to support a single protocol version
40+
- a given version of the plugin only needs to support a single protocol version
41+
42+
— that is, we do not wish to try and implement negotiation of protocol version between ably-cocoa and the plugin.
43+
44+
In order to do this, whenever we increment the CSV2 protocol number in such a way as could cause incompatibility with a plugin, this repo (plugin-api) will make a **breaking API change**, and thus **bump its major version**.
45+
46+
#### Properties to replace
47+
48+
The aforementioned breaking plugin-api change is implemented by replacing the two required protocol properties shown below with equivalents that refer to the new protocol version (e.g. when moving from v6 to v7, rename `usesLiveObjectsProtocolV6` to `usesLiveObjectsProtocolV7`, and similarly rename `compatibleWithProtocolV6` to `compatibleWithProtocolV7`). Note that only one property is needed in order to create a breaking API change, but we provide both so that both parties can check the other's conformance even if package dependencies are not configured correctly.
49+
50+
The current properties are:
51+
52+
In `APPluginAPIProtocol`:
53+
54+
```
55+
/// Whether the SDK uses a protocol version which, as far as a LiveObjects
56+
/// plugin is concerned, is equivalent to protocol v6.
57+
///
58+
/// If the SDK uses a protocol version which is higher than 6 but whose
59+
/// breaking changes compared to v6 do not affect LiveObjects plugins, this
60+
/// property may still return `YES`.
61+
///
62+
/// This property **must** return `YES`. If you wish to introduce a protocol
63+
/// version change, see the "Breaking Realtime protocol version changes"
64+
/// section in the Readme.
65+
@property (nonatomic, readonly) BOOL usesLiveObjectsProtocolV6;
66+
```
67+
68+
> [!NOTE]
69+
> The plugin should perform a runtime assertion that this property returns `YES`, to catch any scenario where package dependencies are incorrectly configured.
70+
71+
In `APLiveObjectsInternalPluginProtocol`:
72+
73+
```
74+
/// Whether this plugin is compatible with protocol v6.
75+
///
76+
/// If this property returns `YES`, it indicates that this plugin can be used
77+
/// with a version of ably-cocoa which uses protocol v6, or which uses a
78+
/// protocol version higher than v6 whose breaking changes compared to v6 do
79+
/// not affect LiveObjects plugins.
80+
///
81+
/// This property **must** return `YES`. If you wish to introduce a protocol
82+
/// version change, see the "Breaking Realtime protocol version changes"
83+
/// section in the Readme.
84+
@property (nonatomic, readonly) BOOL compatibleWithProtocolV6;
85+
```
86+
87+
> [!NOTE]
88+
> ably-cocoa should perform a runtime assertion that this property returns `YES`, to catch any scenario where package dependencies are incorrectly configured.
89+
90+
## Release process for breaking plugin-api changes
91+
92+
The release process in such a scenario is not very smooth; there will be a brief period in which there exists a version of ably-cocoa without a plugin version that is compatible with it. During this window, a user who explicitly updates their `Package.swift` to require the new ably-cocoa version while also depending on the plugin will get a dependency resolution error. To minimise this window, have the plugin release PR reviewed and ready to merge before releasing ably-cocoa, so that the only remaining step is updating the ably-cocoa dependency from a commit pin to the released version tag.
93+
94+
1. Prepare a release PR of plugin version `v_p`, with dependency on the new major version of plugin-api, but still pinned to an ably-cocoa commit. Do not release it.
95+
2. Prepare a release PR of ably-cocoa version `v_c`, with dependency on the new major version of plugin-api. Mention in the release message that it is compatible with version `v_p` of the plugin, which will be released shortly.
96+
3. Release ably-cocoa version `v_c`.
97+
4. Update the release PR of plugin version `v_p` to now point to ably-cocoa version `v_c`.
98+
5. Release plugin version `v_p`.

Sources/_AblyPluginSupportPrivate/include/APLiveObjectsPlugin.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ NS_SWIFT_NAME(LiveObjectsInternalPluginProtocol)
3030
NS_SWIFT_SENDABLE
3131
@protocol APLiveObjectsInternalPluginProtocol <NSObject>
3232

33+
/// Whether this plugin is compatible with protocol v6.
34+
///
35+
/// If this property returns `YES`, it indicates that this plugin can be used
36+
/// with a version of ably-cocoa which uses protocol v6, or which uses a
37+
/// protocol version higher than v6 whose breaking changes compared to v6 do
38+
/// not affect LiveObjects plugins.
39+
///
40+
/// This property **must** return `YES`. If you wish to introduce a protocol
41+
/// version change, see the "Breaking Realtime protocol version changes"
42+
/// section in the Readme.
43+
@property (nonatomic, readonly) BOOL compatibleWithProtocolV6;
44+
3345
/// ably-cocoa will call this method when initializing an `ARTRealtimeChannel` instance.
3446
///
3547
/// The plugin can use this as an opportunity to perform any initial setup of LiveObjects functionality for this channel.

Sources/_AblyPluginSupportPrivate/include/APPluginAPI.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ NS_SWIFT_NAME(PluginAPIProtocol)
1717
NS_SWIFT_SENDABLE
1818
@protocol APPluginAPIProtocol
1919

20+
/// Whether the SDK uses a protocol version which, as far as a LiveObjects
21+
/// plugin is concerned, is equivalent to protocol v6.
22+
///
23+
/// If the SDK uses a protocol version which is higher than 6 but whose
24+
/// breaking changes compared to v6 do not affect LiveObjects plugins, this
25+
/// property may still return `YES`.
26+
///
27+
/// This property **must** return `YES`. If you wish to introduce a protocol
28+
/// version change, see the "Breaking Realtime protocol version changes"
29+
/// section in the Readme.
30+
@property (nonatomic, readonly) BOOL usesLiveObjectsProtocolV6;
31+
2032
/// Returns the internal objects that correspond to a public `ARTRealtimeChannel`.
2133
///
2234
/// Plugins should, in general, not make use of `ARTRealtimeChannel` internally, and instead use `APRealtimeChannel`. This method is intended only to be used in plugin-authored extensions of `ARTRealtimeChannel`.

0 commit comments

Comments
 (0)