main

mattermost/focalboard

Last updated at: 29/12/2023 09:42

plugin_adapter_cluster.go

TLDR

This file is a part of the Demo Projects project and is located at server/ws/plugin_adapter_cluster.go. The file contains two methods and one struct definition:

Methods

sendMessageToCluster

This method is a part of the PluginAdapter struct. It is responsible for sending a message to the cluster. It takes a clusterMessage object as a parameter, which is then serialized to JSON using the json.Marshal function. The serialized message is published as a cluster event using the PublishPluginClusterEvent method of the pa.api object.

HandleClusterEvent

This method is also a part of the PluginAdapter struct. It is responsible for handling a cluster event received by the plugin. It unmarshals the received JSON data into a ClusterMessage object, which contains information about the cluster event. Depending on the content of the ClusterMessage, this method performs different actions such as sending board messages or user messages.

Struct

ClusterMessage

This struct represents a message that is sent to the cluster. It contains the following fields:

  • TeamID (string): The ID of the team.
  • BoardID (string): The ID of the board.
  • UserID (string): The ID of the user.
  • Payload (map[string]interface{}): Additional payload data.
  • EnsureUsers ([]string): An array of user IDs to ensure exist before processing the message.
package ws

import (
	"encoding/json"

	mmModel "github.com/mattermost/mattermost-server/v6/model"
	"github.com/mattermost/mattermost-server/v6/shared/mlog"
)

type ClusterMessage struct {
	TeamID      string
	BoardID     string
	UserID      string
	Payload     map[string]interface{}
	EnsureUsers []string
}

func (pa *PluginAdapter) sendMessageToCluster(clusterMessage *ClusterMessage) {
	const id = "websocket_message"
	b, err := json.Marshal(clusterMessage)
	if err != nil {
		pa.logger.Error("couldn't get JSON bytes from cluster message",
			mlog.String("id", id),
			mlog.Err(err),
		)
		return
	}

	event := mmModel.PluginClusterEvent{Id: id, Data: b}
	opts := mmModel.PluginClusterEventSendOptions{
		SendType: mmModel.PluginClusterEventSendTypeReliable,
	}

	if err := pa.api.PublishPluginClusterEvent(event, opts); err != nil {
		pa.logger.Error("error publishing cluster event",
			mlog.String("id", id),
			mlog.Err(err),
		)
	}
}

func (pa *PluginAdapter) HandleClusterEvent(ev mmModel.PluginClusterEvent) {
	pa.logger.Debug("received cluster event", mlog.String("id", ev.Id))

	var clusterMessage ClusterMessage
	if err := json.Unmarshal(ev.Data, &clusterMessage); err != nil {
		pa.logger.Error("cannot unmarshal cluster message data",
			mlog.String("id", ev.Id),
			mlog.Err(err),
		)
		return
	}

	if clusterMessage.BoardID != "" {
		pa.sendBoardMessageSkipCluster(clusterMessage.TeamID, clusterMessage.BoardID, clusterMessage.Payload, clusterMessage.EnsureUsers...)
		return
	}

	var action string
	if actionRaw, ok := clusterMessage.Payload["action"]; ok {
		if s, ok := actionRaw.(string); ok {
			action = s
		}
	}
	if action == "" {
		// no action was specified in the event; assume block change and warn.
		pa.logger.Warn("cannot determine action from cluster message data",
			mlog.String("id", ev.Id),
			mlog.Map("payload", clusterMessage.Payload),
		)
		return
	}

	if clusterMessage.UserID != "" {
		pa.sendUserMessageSkipCluster(action, clusterMessage.Payload, clusterMessage.UserID)
		return
	}

	pa.sendTeamMessageSkipCluster(action, clusterMessage.TeamID, clusterMessage.Payload)
}