Skip to content

Upgrade to protocol v5: message update/delete/append, PublishResult, Stats rewrite - #450

Draft
matt423 wants to merge 8 commits into
mainfrom
protocal-v5
Draft

Upgrade to protocol v5: message update/delete/append, PublishResult, Stats rewrite#450
matt423 wants to merge 8 commits into
mainfrom
protocal-v5

Conversation

@matt423

Copy link
Copy Markdown

Summary

Upgrades the SDK from protocol version 2 to 5, adding message lifecycle operations and bringing the Stats model in line with the current Ably specification.

  • Update, delete, append messages on REST (channel.update_message, channel.delete_message, channel.append_message) and Realtime channels (RSL15, RTL32)
  • PublishResult returned from publish with message serials (RSL1n, PBR2a)
  • UpdateDeleteResult returned from update/delete/append with version serial (UDR2a)
  • MessageOperation model for operation metadata on update/delete/append (MOP)
  • Complete Message::ACTION enum with all TM5 values (message_create, message_update, message_delete, meta, message_summary, message_append)
  • Stats model rewritten to match spec v2.1+ (TS12): flat entries hash replaces nested accessors; all Stats sub-types removed (TS4–TS9 deleted from spec)

Breaking changes

  • Rest::Channel#publish returns PublishResult instead of Boolean
  • Realtime::Channel#publish deferrable yields PublishResult instead of Message/Array<Message>
  • Stats nested accessors (all, inbound, outbound, persisted, connections, channels, api_requests, token_requests) replaced by flat entries hash (TS12r) — use stat.entries['messages.all.all.count'] instead of stat.all.all.count
  • Stats::MessageTraffic, Stats::MessageTypes, Stats::MessageCount, Stats::ConnectionTypes, Stats::RequestCount, Stats::ResourceCount removed
  • Stats#interval_granularity replaced by Stats#unit (TS12c)

New models

ModelSpecPurpose
PublishResultRSL1n, PBR2aWraps publish response with serials array
UpdateDeleteResultUDR2aWraps update/delete/append response with version_serial
MessageOperationMOPOperation metadata (client_id, description, metadata)

REST examples

client=Ably::Rest::Client.new(key: 'key')channel=client.channels.get('chat')# Publish — now returns PublishResult with serialsresult=channel.publish('greeting','Hello!')serial=result.serials.first#=> "01826232781:0"# Batch publishresult=channel.publish([{name: 'chat',data: 'Hello'},{name: 'chat',data: 'World'}])result.serials#=> ["01826232781:0", "01826232781:1"]# Updatechannel.update_message({serial: serial,data: 'Edited'})# Deletechannel.delete_message({serial: serial})# Appendchannel.append_message({serial: serial,data: {reaction: 'heart'}})# With operation metadatachannel.update_message({serial: serial,data: 'Fixed'},{description: 'Typo fix',metadata: {'reason'=>'spelling'}})

Realtime examples

EventMachine.rundoclient=Ably::Realtime::Client.new(key: 'key')channel=client.channels.get('chat')channel.attachdochannel.publish('greeting','Hello!')do |result|
serial=result.serials.firstchannel.update_message({serial: serial,data: 'Edited'})do |update_result|
putsupdate_result.version_serialclient.connection.close{EventMachine.stop}endendendend

Test plan

  • All 1261 unit tests pass
  • All 2516 acceptance tests pass (0 failures, 5 pending)
  • SPEC.md regenerated with zero failure markers

Implements message update functionality following the Ably specification
(RSL15, RTL32, TM2, TM5, MOP, UDR). Bumps protocol version from 2 to 5
to enable ACK responses with publish result serials.
- Add Message ACTION enum (message_create, message_update) and new
accessors (action, serial, version, created_at, updated_at)
- Add MessageOperation and UpdateDeleteResult model types
- Add REST channel#update_message via PATCH /channels/{name}/messages/{serial}
- Add Realtime channel#update_message via MESSAGE ProtocolMessage
- Add ProtocolMessage#res accessor for protocol v5 ACK results
- Update ACK handling to route UpdateDeleteResult to update deferrables
- Add REST client#patch convenience method
publish now returns PublishResult containing a serials array that maps
1:1 to the published messages, per spec RSL1n / PBR2a.
REST: publish returns PublishResult instead of Boolean. This is
backward-compatible since PublishResult is truthy.
Realtime: publish callbacks now receive PublishResult instead of the
Message object. This is a breaking change for callers that access
message properties (name, data, etc.) in publish callbacks. This
aligns with the spec and matches the JS SDK behavior.
The ACK handler extracts serials from the protocol v5 res field
(TR4s) and constructs per-message PublishResults, which are
aggregated for multi-message publishes in the Publisher module.
Extract shared send_message_action helper from update_message and add
delete_message using MESSAGE_DELETE action. Extend ACTION enum with all
TM5 values (message_delete, meta, message_summary, message_append).
Update ACK handler to return UpdateDeleteResult for delete/append actions.
Add append_message using MESSAGE_APPEND action via the shared
send_message_action helper. Same signature and behavior as
update_message and delete_message.
The protocol version change from 2 to 5 changed the stats API response
format from nested objects to a flat entries dictionary (TS12r). Update
the Stats model to be spec-compliant:
- Replace nested accessors (all, inbound, outbound, etc.) with flat
entries hash
- Add unit, in_progress, schema, app_id accessors (TS12c/q/s/t)
- Remove deleted sub-types: MessageTraffic, MessageTypes, MessageCount,
ConnectionTypes, RequestCount, ResourceCount (TS4-TS9)
- Delete stats_types.rb
New public API: publish returns PublishResult (breaking for Realtime),
update_message, delete_message, append_message on REST and Realtime
channels.
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/features March 2, 2026 14:08 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/docs March 2, 2026 14:08 Inactive
The regex \d\.\d\.\d only matches single-digit version components
but Ruby 3.2.10+ has double-digit patch versions, causing CI failures.
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/features March 2, 2026 14:28 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/docs March 2, 2026 14:28 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/docs March 2, 2026 15:27 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/features March 2, 2026 15:27 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/docs March 2, 2026 15:49 Inactive
@github-actions
github-actionsBottemporarily deployed to staging/pull/450/features March 2, 2026 15:49 Inactive
- Add after(:example) hook to clear stale realtime_clients and stop
EM reactor between tests, preventing leaked state from crashed or
timed-out tests poisoning subsequent EM-dependent tests
- Switch paginated result specs from manual include + run_reactor to
:event_machine metadata tag so they get proper before/around/after
lifecycle hooks
@lmars

Copy link
Copy Markdown
Member

@matt423 I'm going to review this, but just based on the description:

Breaking changes

I don't think we can make this change in a patch release if it includes breaking changes, were you intending this to be a major version bump? If not, then I think we need to do it in a backwards compatible way similar to how we're doing it for Go in ably/ably-go#697 (i.e. by adding a new PublishWithResult method which returns PublishResult whilst leaving Publish the same, and keeping stats the same by sticking with protocol v2 for stats).

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@matt423@lmars