Summary The addition of the TotalMsgCountRoot and MsgCountRoot columns to support CRT caused several issues with previously read threads and channels being marked as unread. Previously we attempted to fix this purely in a SQL migration [MM-35345][MM-35494] fixes for incorrect mentions and unreads for threads and channels #17803 but that turned out to be too heavy and it was decided to break up some of the fixes into async jobs. This PR implements an async job to mark channels as read if there are no user posts since the last time the user viewed the channel. Ticket Link https://mattermost.atlassian.net/browse/MM-37013
115 строки
3.3 KiB
Go
115 строки
3.3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package jobs
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
|
ejobs "github.com/mattermost/mattermost-server/v6/einterfaces/jobs"
|
|
tjobs "github.com/mattermost/mattermost-server/v6/jobs/interfaces"
|
|
"github.com/mattermost/mattermost-server/v6/model"
|
|
"github.com/mattermost/mattermost-server/v6/services/configservice"
|
|
"github.com/mattermost/mattermost-server/v6/store"
|
|
)
|
|
|
|
type JobServer struct {
|
|
ConfigService configservice.ConfigService
|
|
Store store.Store
|
|
metrics einterfaces.MetricsInterface
|
|
|
|
DataRetentionJob ejobs.DataRetentionJobInterface
|
|
MessageExportJob ejobs.MessageExportJobInterface
|
|
ElasticsearchAggregator ejobs.ElasticsearchAggregatorInterface
|
|
ElasticsearchIndexer tjobs.IndexerJobInterface
|
|
LdapSync ejobs.LdapSyncInterface
|
|
Migrations tjobs.MigrationsJobInterface
|
|
Plugins tjobs.PluginsJobInterface
|
|
BleveIndexer tjobs.IndexerJobInterface
|
|
ExpiryNotify tjobs.ExpiryNotifyJobInterface
|
|
ProductNotices tjobs.ProductNoticesJobInterface
|
|
ActiveUsers tjobs.ActiveUsersJobInterface
|
|
ImportProcess tjobs.ImportProcessInterface
|
|
ImportDelete tjobs.ImportDeleteInterface
|
|
ExportProcess tjobs.ExportProcessInterface
|
|
ExportDelete tjobs.ExportDeleteInterface
|
|
Cloud ejobs.CloudJobInterface
|
|
ResendInvitationEmails ejobs.ResendInvitationEmailJobInterface
|
|
ExtractContent tjobs.ExtractContentInterface
|
|
FixCRTChannelUnreads tjobs.FixCRTChannelUnreadsJobInterface
|
|
|
|
// mut is used to protect the following fields from concurrent access.
|
|
mut sync.Mutex
|
|
workers *Workers
|
|
schedulers *Schedulers
|
|
}
|
|
|
|
func NewJobServer(configService configservice.ConfigService, store store.Store, metrics einterfaces.MetricsInterface) *JobServer {
|
|
return &JobServer{
|
|
ConfigService: configService,
|
|
Store: store,
|
|
metrics: metrics,
|
|
}
|
|
}
|
|
|
|
func (srv *JobServer) Config() *model.Config {
|
|
return srv.ConfigService.Config()
|
|
}
|
|
|
|
func (srv *JobServer) StartWorkers() error {
|
|
srv.mut.Lock()
|
|
defer srv.mut.Unlock()
|
|
if srv.workers == nil {
|
|
return ErrWorkersUninitialized
|
|
} else if srv.workers.running {
|
|
return ErrWorkersRunning
|
|
}
|
|
srv.workers.Start()
|
|
return nil
|
|
}
|
|
|
|
func (srv *JobServer) StartSchedulers() error {
|
|
srv.mut.Lock()
|
|
defer srv.mut.Unlock()
|
|
if srv.schedulers == nil {
|
|
return ErrSchedulersUninitialized
|
|
} else if srv.schedulers.running {
|
|
return ErrSchedulersRunning
|
|
}
|
|
srv.schedulers.Start()
|
|
return nil
|
|
}
|
|
|
|
func (srv *JobServer) StopWorkers() error {
|
|
srv.mut.Lock()
|
|
defer srv.mut.Unlock()
|
|
if srv.workers == nil {
|
|
return ErrWorkersUninitialized
|
|
} else if !srv.workers.running {
|
|
return ErrWorkersNotRunning
|
|
}
|
|
srv.workers.Stop()
|
|
return nil
|
|
}
|
|
|
|
func (srv *JobServer) StopSchedulers() error {
|
|
srv.mut.Lock()
|
|
defer srv.mut.Unlock()
|
|
if srv.schedulers == nil {
|
|
return ErrSchedulersUninitialized
|
|
} else if !srv.schedulers.running {
|
|
return ErrSchedulersNotRunning
|
|
}
|
|
srv.schedulers.Stop()
|
|
return nil
|
|
}
|
|
|
|
func (srv *JobServer) HandleClusterLeaderChange(isLeader bool) {
|
|
srv.mut.Lock()
|
|
defer srv.mut.Unlock()
|
|
if srv.schedulers != nil {
|
|
srv.schedulers.handleClusterLeaderChange(isLeader)
|
|
}
|
|
}
|