diff --git a/proto/decentraland/social_service/v2/social_service_v2.proto b/proto/decentraland/social_service/v2/social_service_v2.proto index 5cddad29..ee8dbba0 100644 --- a/proto/decentraland/social_service/v2/social_service_v2.proto +++ b/proto/decentraland/social_service/v2/social_service_v2.proto @@ -112,6 +112,30 @@ message UpsertFriendshipResponse { } } +// Subscription stream lifecycle + +// Reason codes for a server-initiated closure of a subscription stream. Only reasons that +// can actually be delivered are listed: a close notice reaches the client as the final +// stream message, which requires the connection to still be alive. That rules out +// shutdown/stale-cleanup closes, where the socket is already gone before the server tears +// the subscription down. +enum SubscriptionStreamClosedReason { + // The server did not specify a finer-grained reason. + STREAM_CLOSED_UNKNOWN = 0; + // The connection already has an active subscription for this stream. + STREAM_CLOSED_DUPLICATE_SUBSCRIPTION = 1; +} + +// Sent by the server as the FINAL message of a subscription stream to inform the +// client why the stream is being closed. When the `stream_closed` field is present +// on a streamed update, the message carries no update data and the stream ends +// right after it. +message SubscriptionStreamClosed { + SubscriptionStreamClosedReason reason = 1; + // Optional human-readable detail, meant for logging/debugging (not for UI). + optional string message = 2; +} + message FriendshipUpdate { message RequestResponse { FriendProfile friend = 1; @@ -133,11 +157,19 @@ message FriendshipUpdate { CancelResponse cancel = 5; BlockResponse block = 6; } + + // Present only on the final message of the stream; explains why the server closed it. + // When set, the `update` oneof is unset. + optional SubscriptionStreamClosed stream_closed = 7; } message FriendConnectivityUpdate { FriendProfile friend = 1; ConnectivityStatus status = 2; + + // Present only on the final message of the stream; explains why the server closed it. + // When set, all other fields are unset. + optional SubscriptionStreamClosed stream_closed = 3; } message GetFriendshipStatusPayload { @@ -288,12 +320,20 @@ message GetBlockingStatusResponse { message BlockUpdate { string address = 1; bool is_blocked = 2; + + // Present only on the final message of the stream; explains why the server closed it. + // When set, all other fields are unset. + optional SubscriptionStreamClosed stream_closed = 3; } message CommunityMemberConnectivityUpdate { string community_id = 1; User member = 2; ConnectivityStatus status = 3; + + // Present only on the final message of the stream; explains why the server closed it. + // When set, all other fields are unset. + optional SubscriptionStreamClosed stream_closed = 4; } // Private voice chats @@ -378,6 +418,10 @@ message PrivateVoiceChatUpdate { optional User caller = 3; optional User callee = 4; optional PrivateVoiceChatCredentials credentials = 5; + + // Present only on the final message of the stream; explains why the server closed it. + // When set, all other fields are unset. + optional SubscriptionStreamClosed stream_closed = 6; } // Ending a private voice chat @@ -618,6 +662,10 @@ message CommunityVoiceChatUpdate { string community_name = 7; // Name of the community optional string community_image = 8; // Image/picture of the community repeated string worlds = 9; // World names associated with the community (world: true) + + // Present only on the final message of the stream; explains why the server closed it. + // When set, all other fields are unset. + optional SubscriptionStreamClosed stream_closed = 10; } service SocialService {