* Creating empty Channels shell

This is the first step in moving to a product-based
isolated architecture.

For now, Channels is empty and does not contain anything.

Next step is to change App to contain Channels instead
of Server. Some of the initialization code in NewServer
would need to be moved inside NewChannels.

This would complete the full pass-through mode of accessing
everything.

The last step would be to gradually move Channels related
fields from Server into Channels, keeping Server to be
just the global level struct.

```release-note
NONE
```

* fix vet failure

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2021-10-11 19:24:50 +05:30
коммит произвёл GitHub
родитель 55ea07677d
Коммит 561bc968c8
4 изменённых файлов: 78 добавлений и 0 удалений

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

@@ -20,6 +20,9 @@ import (
"github.com/mattermost/mattermost-server/v6/utils"
)
// App is a pure functional component that does not have any fields, except Server.
// It is a request-scoped struct constructed every time a request hits the server,
// and its only purpose is to provide business logic to Server via its methods.
type App struct {
srv *Server
}

29
app/channels.go Обычный файл
Просмотреть файл

@@ -0,0 +1,29 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
// Channels contains all channels related state.
type Channels struct {
s *Server
}
func init() {
RegisterProduct("channels", func(s *Server) (Product, error) {
return NewChannels(s)
})
}
func NewChannels(s *Server) (*Channels, error) {
return &Channels{
s: s,
}, nil
}
func (c *Channels) Start() error {
return nil
}
func (c *Channels) Stop() error {
return nil
}

15
app/product.go Обычный файл
Просмотреть файл

@@ -0,0 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
type Product interface {
Start() error
Stop() error
}
var products = make(map[string]func(*Server) (Product, error))
func RegisterProduct(name string, f func(*Server) (Product, error)) {
products[name] = f
}

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

@@ -209,6 +209,8 @@ type Server struct {
dndTaskMut sync.Mutex
dndTask *model.ScheduledTask
products map[string]Product
}
func NewServer(options ...Option) (*Server, error) {
@@ -222,6 +224,7 @@ func NewServer(options ...Option) (*Server, error) {
licenseListeners: map[string]func(*model.License, *model.License){},
hashSeed: maphash.MakeSeed(),
uploadLockMap: map[string]bool{},
products: make(map[string]Product),
}
for _, option := range options {
@@ -691,6 +694,17 @@ func NewServer(options ...Option) (*Server, error) {
s.ShutDownPlugins()
}
})
// Initialize products
for name, initializer := range products {
prod, err := initializer(s)
if err != nil {
return nil, errors.Wrapf(err, "error initializing product: %s", name)
}
s.products[name] = prod
}
s.AddConfigListener(func(oldCfg, newCfg *model.Config) {
if !oldCfg.FeatureFlags.TimedDND && newCfg.FeatureFlags.TimedDND {
runDNDStatusExpireJob(app)
@@ -985,6 +999,15 @@ func (s *Server) Shutdown() {
defer sentry.Flush(2 * time.Second)
// Stop products.
// This needs to happen before because products are dependent
// on parent services.
for name, product := range s.products {
if err := product.Stop(); err != nil {
mlog.Warn("Unable to cleanly stop product", mlog.String("name", name), mlog.Err(err))
}
}
s.HubStop()
s.ShutDownPlugins()
s.RemoveLicenseListener(s.licenseListenerId)
@@ -1380,6 +1403,14 @@ func (s *Server) Start() error {
mlog.Error("Error starting inter-cluster services", mlog.Err(err))
}
// Start products.
// This needs to happen after the server has started.
for name, product := range s.products {
if err := product.Start(); err != nil {
return errors.Wrapf(err, "Unable to start %s", name)
}
}
return nil
}