* Posts * Add missing translation * Fix internal store marshaling * [MM-22051] Remove To/From JSON (Channels) (#18116) * Channels * Channel members * ChannelSearch * Channel categories, list, sidebar, stats, view * Fix conversions * [MM-22051] Remove To/From JSON (Users) (#18121) * User related structs * Fix return * Team related structures (#18127) * [MM-22051] Remove To/From JSON (Status, Bot, Reaction, Thread, FileInfo) (#18130) * Status * Bot * Reaction * Thread * FileInfo * Some fixes * Translations update from Weblate (#18143) * Translated using Weblate (German) Currently translated at 100.0% (2309 of 2309 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/de/ * Translated using Weblate (Turkish) Currently translated at 100.0% (2309 of 2309 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/tr/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2309 of 2309 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/hu/ * Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ * Translated using Weblate (German) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/de/ * Translated using Weblate (Turkish) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/tr/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/hu/ * Translated using Weblate (English (Australia)) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/en_AU/ * Translated using Weblate (Bulgarian) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/bg/ * Translated using Weblate (Japanese) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/ja/ * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (2301 of 2301 strings) Translation: mattermost-languages-shipped/mattermost-server Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server_master/zh_Hans/ Co-authored-by: JtheBAB <srast@bioc.uzh.ch> Co-authored-by: Kaya Zeren <kayazeren@gmail.com> Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu> Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au> Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com> Co-authored-by: kaakaa <stooner.hoe@gmail.com> Co-authored-by: aeomin <lin@aeomin.net> Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: JtheBAB <srast@bioc.uzh.ch> Co-authored-by: Kaya Zeren <kayazeren@gmail.com> Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu> Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au> Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com> Co-authored-by: kaakaa <stooner.hoe@gmail.com> Co-authored-by: aeomin <lin@aeomin.net> * [MM-22051] Remove To/From JSON methods from model (#18138) * Scheme * Role * Session * Config * Status * Fix logic * Emoji * GuestsInvite * Group * Command * ClusterInfo * License * Job * System * Plugin * Command2 * IncomingWebhook * OutgoingWebhook * Fix tests * Update traslation * Some fixes * Add missing return * Simplify * Make Config.ToJSONFiltered() return []byte * Make Busy.ToJSON() return []byte * Include error in log * Split logic * [MM-22051] Remove To/From JSON (final) (#18150) * SwitchRequest * PluginEventData * Permalink * PushNotification * SuggestCommand * PluginsResponse * WebSocketMessage * RemoteCluster * SharedChannel * PluginStatuses * InitialLoad * ClusterDiscovery * ClusterStats * MfaSecret * GroupSyncable * SAML * WebSocketRequest * TypingRequest * SecurityBulletin * OAuthApp * IntegrationAction * DataRetention * Preference * FileInfoList * Compliance * Preferences * FileInfoSearchResults * TermsOfService * InstallMarketplacePluginRequest * GitLabUser * UploadSessions * Remove unused helpers * Fix tests * [MM-23280] Fix linting for ToJSON/FromJSON (#18153) * SwitchRequest * PluginEventData * Permalink * PushNotification * SuggestCommand * PluginsResponse * WebSocketMessage * RemoteCluster * SharedChannel * PluginStatuses * InitialLoad * ClusterDiscovery * ClusterStats * MfaSecret * GroupSyncable * SAML * WebSocketRequest * TypingRequest * SecurityBulletin * OAuthApp * IntegrationAction * DataRetention * Preference * FileInfoList * Compliance * Preferences * FileInfoSearchResults * TermsOfService * InstallMarketplacePluginRequest * GitLabUser * UploadSessions * Remove unused helpers * Fix tests * Fix linting for ToJSON/FromJSON * Fix conversions Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: JtheBAB <srast@bioc.uzh.ch> Co-authored-by: Kaya Zeren <kayazeren@gmail.com> Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu> Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au> Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com> Co-authored-by: kaakaa <stooner.hoe@gmail.com> Co-authored-by: aeomin <lin@aeomin.net> Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
156 строки
3.7 KiB
Go
156 строки
3.7 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
|
"github.com/mattermost/mattermost-server/v6/model"
|
|
)
|
|
|
|
const (
|
|
TimestampFormat = "Mon Jan 2 15:04:05 -0700 MST 2006"
|
|
)
|
|
|
|
// Busy represents the busy state of the server. A server marked busy
|
|
// will have non-critical services disabled. If a Cluster is provided
|
|
// any changes will be propagated to each node.
|
|
type Busy struct {
|
|
busy int32 // protected via atomic for fast IsBusy calls
|
|
mux sync.RWMutex
|
|
timer *time.Timer
|
|
expires time.Time
|
|
|
|
cluster einterfaces.ClusterInterface
|
|
}
|
|
|
|
// NewBusy creates a new Busy instance with optional cluster which will
|
|
// be notified of busy state changes.
|
|
func NewBusy(cluster einterfaces.ClusterInterface) *Busy {
|
|
return &Busy{cluster: cluster}
|
|
}
|
|
|
|
// IsBusy returns true if the server has been marked as busy.
|
|
func (b *Busy) IsBusy() bool {
|
|
if b == nil {
|
|
return false
|
|
}
|
|
return atomic.LoadInt32(&b.busy) != 0
|
|
}
|
|
|
|
// Set marks the server as busy for dur duration and notifies cluster nodes.
|
|
func (b *Busy) Set(dur time.Duration) {
|
|
b.mux.Lock()
|
|
defer b.mux.Unlock()
|
|
|
|
// minimum 1 second
|
|
if dur < (time.Second * 1) {
|
|
dur = time.Second * 1
|
|
}
|
|
|
|
b.setWithoutNotify(dur)
|
|
|
|
if b.cluster != nil {
|
|
sbs := &model.ServerBusyState{Busy: true, Expires: b.expires.Unix(), ExpiresTS: b.expires.UTC().Format(TimestampFormat)}
|
|
b.notifyServerBusyChange(sbs)
|
|
}
|
|
}
|
|
|
|
// must hold mutex
|
|
func (b *Busy) setWithoutNotify(dur time.Duration) {
|
|
b.clearWithoutNotify()
|
|
atomic.StoreInt32(&b.busy, 1)
|
|
b.expires = time.Now().Add(dur)
|
|
b.timer = time.AfterFunc(dur, func() {
|
|
b.mux.Lock()
|
|
b.clearWithoutNotify()
|
|
b.mux.Unlock()
|
|
})
|
|
}
|
|
|
|
// ClearBusy marks the server as not busy and notifies cluster nodes.
|
|
func (b *Busy) Clear() {
|
|
b.mux.Lock()
|
|
defer b.mux.Unlock()
|
|
|
|
b.clearWithoutNotify()
|
|
|
|
if b.cluster != nil {
|
|
sbs := &model.ServerBusyState{Busy: false, Expires: time.Time{}.Unix(), ExpiresTS: ""}
|
|
b.notifyServerBusyChange(sbs)
|
|
}
|
|
}
|
|
|
|
// must hold mutex
|
|
func (b *Busy) clearWithoutNotify() {
|
|
if b.timer != nil {
|
|
b.timer.Stop() // don't drain timer.C channel for AfterFunc timers.
|
|
}
|
|
b.timer = nil
|
|
b.expires = time.Time{}
|
|
atomic.StoreInt32(&b.busy, 0)
|
|
}
|
|
|
|
// Expires returns the expected time that the server
|
|
// will be marked not busy. This expiry can be extended
|
|
// via additional calls to SetBusy.
|
|
func (b *Busy) Expires() time.Time {
|
|
b.mux.RLock()
|
|
defer b.mux.RUnlock()
|
|
return b.expires
|
|
}
|
|
|
|
// notifyServerBusyChange informs all cluster members of a server busy state change.
|
|
func (b *Busy) notifyServerBusyChange(sbs *model.ServerBusyState) {
|
|
if b.cluster == nil {
|
|
return
|
|
}
|
|
buf, _ := json.Marshal(sbs)
|
|
msg := &model.ClusterMessage{
|
|
Event: model.ClusterEventBusyStateChanged,
|
|
SendType: model.ClusterSendReliable,
|
|
WaitForAllToSend: true,
|
|
Data: buf,
|
|
}
|
|
b.cluster.SendClusterMessage(msg)
|
|
}
|
|
|
|
// ClusterEventChanged is called when a CLUSTER_EVENT_BUSY_STATE_CHANGED is received.
|
|
func (b *Busy) ClusterEventChanged(sbs *model.ServerBusyState) {
|
|
b.mux.Lock()
|
|
defer b.mux.Unlock()
|
|
|
|
if sbs.Busy {
|
|
expires := time.Unix(sbs.Expires, 0)
|
|
dur := time.Until(expires)
|
|
if dur > 0 {
|
|
b.setWithoutNotify(dur)
|
|
}
|
|
} else {
|
|
b.clearWithoutNotify()
|
|
}
|
|
}
|
|
|
|
func (b *Busy) ToJSON() ([]byte, error) {
|
|
b.mux.RLock()
|
|
defer b.mux.RUnlock()
|
|
|
|
sbs := &model.ServerBusyState{
|
|
Busy: atomic.LoadInt32(&b.busy) != 0,
|
|
Expires: b.expires.Unix(),
|
|
ExpiresTS: b.expires.UTC().Format(TimestampFormat),
|
|
}
|
|
sbsJSON, jsonErr := json.Marshal(sbs)
|
|
if jsonErr != nil {
|
|
return []byte{}, fmt.Errorf("failed to encode server busy state to JSON: %w", jsonErr)
|
|
}
|
|
|
|
return sbsJSON, nil
|
|
}
|