коммит произвёл
GitHub
родитель
7e728d0b6f
Коммит
3bc151bbda
215
app/server.go
215
app/server.go
@@ -227,11 +227,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Following outlines the specific set of steps
|
||||
// performed during server bootup. They are sensitive to order
|
||||
// and has dependency requirements with the previous step.
|
||||
//
|
||||
// Step 1: Config.
|
||||
if s.configStore == nil {
|
||||
innerStore, err := config.NewFileStore("config.json")
|
||||
if err != nil {
|
||||
@@ -245,18 +240,30 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
s.configStore = configStore
|
||||
}
|
||||
|
||||
// Step 2: Logging
|
||||
if err := s.initLogging(); err != nil {
|
||||
mlog.Error("Could not initiate logging", mlog.Err(err))
|
||||
}
|
||||
|
||||
var imgErr error
|
||||
s.imgDecoder, imgErr = imaging.NewDecoder(imaging.DecoderOptions{
|
||||
ConcurrencyLevel: runtime.NumCPU(),
|
||||
})
|
||||
if imgErr != nil {
|
||||
return nil, errors.Wrap(imgErr, "failed to create image decoder")
|
||||
}
|
||||
s.imgEncoder, imgErr = imaging.NewEncoder(imaging.EncoderOptions{
|
||||
ConcurrencyLevel: runtime.NumCPU(),
|
||||
})
|
||||
if imgErr != nil {
|
||||
return nil, errors.Wrap(imgErr, "failed to create image encoder")
|
||||
}
|
||||
|
||||
// This is called after initLogging() to avoid a race condition.
|
||||
mlog.Info("Server is initializing...", mlog.String("go_version", runtime.Version()))
|
||||
|
||||
s.httpService = httpservice.MakeHTTPService(s)
|
||||
|
||||
// Step 3: Initialize products.
|
||||
// Depends on s.httpService.
|
||||
// Initialize products
|
||||
for name, initializer := range products {
|
||||
prod, err := initializer(s)
|
||||
if err != nil {
|
||||
@@ -266,8 +273,49 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
s.products[name] = prod
|
||||
}
|
||||
|
||||
// Step 4: Search Engine
|
||||
// Depends on Step 1 (config).
|
||||
// It is important to initialize the hub only after the global logger is set
|
||||
// to avoid race conditions while logging from inside the hub.
|
||||
s.HubStart()
|
||||
|
||||
if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry {
|
||||
if strings.Contains(SentryDSN, "placeholder") {
|
||||
mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.")
|
||||
} else {
|
||||
if err := sentry.Init(sentry.ClientOptions{
|
||||
Dsn: SentryDSN,
|
||||
Release: model.BuildHash,
|
||||
AttachStacktrace: true,
|
||||
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
||||
// sanitize data sent to sentry to reduce exposure of PII
|
||||
if event.Request != nil {
|
||||
event.Request.Cookies = ""
|
||||
event.Request.QueryString = ""
|
||||
event.Request.Headers = nil
|
||||
event.Request.Data = ""
|
||||
}
|
||||
return event
|
||||
},
|
||||
}); err != nil {
|
||||
mlog.Warn("Sentry could not be initiated, probably bad DSN?", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if *s.Config().ServiceSettings.EnableOpenTracing {
|
||||
tracer, err := tracing.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.tracer = tracer
|
||||
}
|
||||
|
||||
s.pushNotificationClient = s.httpService.MakeClient(true)
|
||||
|
||||
if err := utils.TranslationsPreInit(); err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to load Mattermost translation files")
|
||||
}
|
||||
model.AppErrorInit(i18n.T)
|
||||
|
||||
searchEngine := searchengine.NewBroker(s.Config())
|
||||
bleveEngine := bleveengine.NewBleveEngine(s.Config())
|
||||
if err := bleveEngine.Start(); err != nil {
|
||||
@@ -276,25 +324,41 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
searchEngine.RegisterBleveEngine(bleveEngine)
|
||||
s.SearchEngine = searchEngine
|
||||
|
||||
// Step 5: Init Enterprise
|
||||
// Depends on step 3 (s.Channels() must be non-nil)
|
||||
// and step 4 (s.SearchEngine must be non-nil)
|
||||
s.initEnterprise()
|
||||
|
||||
// Step 6: Cache provider.
|
||||
// At the moment we only have this implementation
|
||||
// at the moment we only have this implementation
|
||||
// in the future the cache provider will be built based on the loaded config
|
||||
s.CacheProvider = cache.NewProvider()
|
||||
if err := s.CacheProvider.Connect(); err != nil {
|
||||
return nil, errors.Wrapf(err, "Unable to connect to cache provider")
|
||||
}
|
||||
|
||||
// It is important to initialize the hub only after the global logger is set
|
||||
// to avoid race conditions while logging from inside the hub.
|
||||
s.HubStart()
|
||||
var err error
|
||||
if s.seenPendingPostIdsCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PendingPostIDsCacheSize,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create pending post ids cache")
|
||||
}
|
||||
if s.statusCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.StatusCacheSize,
|
||||
Striped: true,
|
||||
StripedBuckets: maxInt(runtime.NumCPU()-1, 1),
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create status cache")
|
||||
}
|
||||
if s.openGraphDataCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: openGraphMetadataCacheSize,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create opengraphdata cache")
|
||||
}
|
||||
|
||||
s.createPushNotificationsHub()
|
||||
|
||||
if err2 := i18n.InitTranslations(*s.Config().LocalizationSettings.DefaultServerLocale, *s.Config().LocalizationSettings.DefaultClientLocale); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
|
||||
// initEnterprise needs to be called after products initialization.
|
||||
s.initEnterprise()
|
||||
|
||||
// Step 7: Store.
|
||||
// Depends on Step 1 (config), 5 (metrics, cluster) and 6 (cacheProvider).
|
||||
if s.newStore == nil {
|
||||
s.newStore = func() (store.Store, error) {
|
||||
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.Metrics)
|
||||
@@ -331,81 +395,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
s.Store, err = s.newStore()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create store")
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Everything below this is not order sensitive and safe to be moved around.
|
||||
// If you are adding a new field that is non-channels specific, please add
|
||||
// below this. Otherwise, please add it to Channels struct in app/channels.go.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if *s.Config().LogSettings.EnableDiagnostics && *s.Config().LogSettings.EnableSentry {
|
||||
if strings.Contains(SentryDSN, "placeholder") {
|
||||
mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.")
|
||||
} else {
|
||||
if err2 := sentry.Init(sentry.ClientOptions{
|
||||
Dsn: SentryDSN,
|
||||
Release: model.BuildHash,
|
||||
AttachStacktrace: true,
|
||||
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
||||
// sanitize data sent to sentry to reduce exposure of PII
|
||||
if event.Request != nil {
|
||||
event.Request.Cookies = ""
|
||||
event.Request.QueryString = ""
|
||||
event.Request.Headers = nil
|
||||
event.Request.Data = ""
|
||||
}
|
||||
return event
|
||||
},
|
||||
}); err2 != nil {
|
||||
mlog.Warn("Sentry could not be initiated, probably bad DSN?", mlog.Err(err2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if *s.Config().ServiceSettings.EnableOpenTracing {
|
||||
tracer, err2 := tracing.New()
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
s.tracer = tracer
|
||||
}
|
||||
|
||||
s.pushNotificationClient = s.httpService.MakeClient(true)
|
||||
|
||||
if err2 := utils.TranslationsPreInit(); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
model.AppErrorInit(i18n.T)
|
||||
|
||||
if s.seenPendingPostIdsCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PendingPostIDsCacheSize,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create pending post ids cache")
|
||||
}
|
||||
if s.statusCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.StatusCacheSize,
|
||||
Striped: true,
|
||||
StripedBuckets: maxInt(runtime.NumCPU()-1, 1),
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create status cache")
|
||||
}
|
||||
if s.openGraphDataCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: openGraphMetadataCacheSize,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create opengraphdata cache")
|
||||
}
|
||||
|
||||
s.createPushNotificationsHub()
|
||||
|
||||
if err2 := i18n.InitTranslations(*s.Config().LocalizationSettings.DefaultServerLocale, *s.Config().LocalizationSettings.DefaultClientLocale); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
|
||||
templatesDir, ok := templates.GetTemplateDirectory()
|
||||
if !ok {
|
||||
return nil, errors.New("Failed find server templates in \"templates\" directory or MM_SERVER_PATH")
|
||||
@@ -421,6 +410,11 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
})
|
||||
s.htmlTemplateWatcher = htmlTemplateWatcher
|
||||
|
||||
s.Store, err = s.newStore()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create store")
|
||||
}
|
||||
|
||||
s.userService, err = users.New(users.ServiceConfig{
|
||||
UserStore: s.Store.User(),
|
||||
SessionStore: s.Store.Session(),
|
||||
@@ -714,20 +708,6 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
}
|
||||
})
|
||||
|
||||
var imgErr error
|
||||
s.imgDecoder, imgErr = imaging.NewDecoder(imaging.DecoderOptions{
|
||||
ConcurrencyLevel: runtime.NumCPU(),
|
||||
})
|
||||
if imgErr != nil {
|
||||
return nil, errors.Wrap(imgErr, "failed to create image decoder")
|
||||
}
|
||||
s.imgEncoder, imgErr = imaging.NewEncoder(imaging.EncoderOptions{
|
||||
ConcurrencyLevel: runtime.NumCPU(),
|
||||
})
|
||||
if imgErr != nil {
|
||||
return nil, errors.Wrap(imgErr, "failed to create image encoder")
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -2290,6 +2270,19 @@ func (s *Server) ReadFile(path string) ([]byte, *model.AppError) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// func (s *Server) WriteFile(fr io.Reader, path string) (int64, *model.AppError) {
|
||||
// backend, err := s.FileBackend()
|
||||
// if err != nil {
|
||||
// return 0, err
|
||||
// }
|
||||
|
||||
// result, nErr := backend.WriteFile(fr, path)
|
||||
// if nErr != nil {
|
||||
// return result, model.NewAppError("WriteFile", "api.file.write_file.app_error", nil, nErr.Error(), http.StatusInternalServerError)
|
||||
// }
|
||||
// return result, nil
|
||||
// }
|
||||
|
||||
func createDNDStatusExpirationRecurringTask(a *App) {
|
||||
a.ch.srv.dndTaskMut.Lock()
|
||||
a.ch.srv.dndTask = model.CreateRecurringTaskFromNextIntervalTime("Unset DND Statuses", a.UpdateDNDStatusOfUsers, 5*time.Minute)
|
||||
|
||||
Ссылка в новой задаче
Block a user