MM-61033: [Shared Channels] Removing a shared channel on one end should make the other remove the shared channel too (#30738)

Этот коммит содержится в:
catalintomai
2025-06-16 16:25:00 +02:00
коммит произвёл GitHub
родитель 7fad136933
Коммит ed3a6d6b91
6 изменённых файлов: 571 добавлений и 12 удалений

Просмотреть файл

@@ -1011,18 +1011,34 @@ func (scs *Service) sendSyncMsgToRemote(msg *model.SyncMsg, rc *model.RemoteClus
err = rcs.SendMsg(ctx, rcMsg, rc, func(rcMsg model.RemoteClusterMsg, rc *model.RemoteCluster, rcResp *remotecluster.Response, errResp error) {
defer wg.Done()
var syncResp model.SyncResponse
if err2 := json.Unmarshal(rcResp.Payload, &syncResp); err2 != nil {
scs.server.Log().Log(mlog.LvlSharedChannelServiceError, "Invalid sync msg response from remote cluster",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
mlog.Err(err2),
)
// Check for ErrChannelNotShared in the application response
if rcResp != nil && !rcResp.IsSuccess() && strings.Contains(rcResp.Err, ErrChannelNotShared.Error()) {
scs.handleChannelNotSharedError(msg, rc)
return
}
if f != nil {
f(syncResp, errResp)
var syncResp model.SyncResponse
if errResp == nil {
if rcResp != nil && len(rcResp.Payload) > 0 {
if err2 := json.Unmarshal(rcResp.Payload, &syncResp); err2 != nil {
scs.server.Log().Log(mlog.LvlSharedChannelServiceError, "Invalid sync msg response from remote cluster",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
mlog.Err(err2),
)
return
}
if f != nil {
f(syncResp, errResp)
}
} else {
// No error but response is nil or empty
scs.server.Log().Log(mlog.LvlSharedChannelServiceError, "Empty or nil response payload from remote cluster",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
)
}
}
})
@@ -1049,3 +1065,45 @@ func sanitizeSyncData(sd *syncData) {
sd.profileImages[id] = sanitizeUserForSync(user)
}
}
// handleChannelNotSharedError processes the case when a remote indicates a channel
// is no longer shared. It removes the remote from the shared channel locally and,
// if it was the last remote, completely unshares the channel.
func (scs *Service) handleChannelNotSharedError(msg *model.SyncMsg, rc *model.RemoteCluster) {
logger := scs.server.Log()
logger.Log(mlog.LvlSharedChannelServiceDebug, "Remote indicated channel is no longer shared; unsharing locally",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
)
// Get the SharedChannelRemote record for this channel and remote
scr, getErr := scs.server.GetStore().SharedChannel().GetRemoteByIds(msg.ChannelId, rc.RemoteId)
if getErr != nil {
logger.Log(mlog.LvlSharedChannelServiceError, "Failed to get shared channel remote",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
mlog.Err(getErr),
)
return
}
// Get channel details for posting the system message
channel, channelErr := scs.server.GetStore().Channel().Get(msg.ChannelId, true)
if channelErr != nil {
logger.Log(mlog.LvlSharedChannelServiceError, "Failed to get channel details",
mlog.String("remote", rc.Name),
mlog.String("channel_id", msg.ChannelId),
mlog.Err(channelErr),
)
return
}
// Post a system message to notify users that the channel is no longer shared with this remote
scs.postUnshareNotification(msg.ChannelId, scr.CreatorId, channel, rc)
if err := scs.UninviteRemoteFromChannel(msg.ChannelId, rc.RemoteId); err != nil {
logger.Log(mlog.LvlSharedChannelServiceError, "Failed to uninvite remote from shared channel", mlog.Err(err))
return
}
}