Remote Cluster Service
- provides ability for multiple Mattermost cluster instances to create a trusted connection with each other and exchange messages
- trusted connections are managed via slash commands (for now)
- facilitates features requiring inter-cluster communication, such as Shared Channels
Shared Channels Service
- provides ability to shared channels between one or more Mattermost cluster instances (using trusted connection)
- sharing/unsharing of channels is managed via slash commands (for now)
Этот коммит содержится в:
Doug Lauder
2021-04-01 13:44:56 -04:00
коммит произвёл GitHub
родитель ff980266ac
Коммит 02196e04fa
137 изменённых файлов: 15137 добавлений и 262 удалений

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

@@ -38,9 +38,11 @@ type TimerLayer struct {
PreferenceStore store.PreferenceStore
ProductNoticesStore store.ProductNoticesStore
ReactionStore store.ReactionStore
RemoteClusterStore store.RemoteClusterStore
RoleStore store.RoleStore
SchemeStore store.SchemeStore
SessionStore store.SessionStore
SharedChannelStore store.SharedChannelStore
StatusStore store.StatusStore
SystemStore store.SystemStore
TeamStore store.TeamStore
@@ -134,6 +136,10 @@ func (s *TimerLayer) Reaction() store.ReactionStore {
return s.ReactionStore
}
func (s *TimerLayer) RemoteCluster() store.RemoteClusterStore {
return s.RemoteClusterStore
}
func (s *TimerLayer) Role() store.RoleStore {
return s.RoleStore
}
@@ -146,6 +152,10 @@ func (s *TimerLayer) Session() store.SessionStore {
return s.SessionStore
}
func (s *TimerLayer) SharedChannel() store.SharedChannelStore {
return s.SharedChannelStore
}
func (s *TimerLayer) Status() store.StatusStore {
return s.StatusStore
}
@@ -290,6 +300,11 @@ type TimerLayerReactionStore struct {
Root *TimerLayer
}
type TimerLayerRemoteClusterStore struct {
store.RemoteClusterStore
Root *TimerLayer
}
type TimerLayerRoleStore struct {
store.RoleStore
Root *TimerLayer
@@ -305,6 +320,11 @@ type TimerLayerSessionStore struct {
Root *TimerLayer
}
type TimerLayerSharedChannelStore struct {
store.SharedChannelStore
Root *TimerLayer
}
type TimerLayerStatusStore struct {
store.StatusStore
Root *TimerLayer
@@ -615,10 +635,10 @@ func (s *TimerLayerChannelStore) CountPostsAfter(channelID string, timestamp int
return result, resultVar1, err
}
func (s *TimerLayerChannelStore) CreateDirectChannel(userId *model.User, otherUserId *model.User) (*model.Channel, error) {
func (s *TimerLayerChannelStore) CreateDirectChannel(userId *model.User, otherUserId *model.User, channelOptions ...model.ChannelOption) (*model.Channel, error) {
start := timemodule.Now()
result, err := s.ChannelStore.CreateDirectChannel(userId, otherUserId)
result, err := s.ChannelStore.CreateDirectChannel(userId, otherUserId, channelOptions...)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
@@ -1415,6 +1435,22 @@ func (s *TimerLayerChannelStore) GetTeamChannels(teamID string) (*model.ChannelL
return result, err
}
func (s *TimerLayerChannelStore) GetTeamForChannel(channelID string) (*model.Team, error) {
start := timemodule.Now()
result, err := s.ChannelStore.GetTeamForChannel(channelID)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.GetTeamForChannel", success, elapsed)
}
return result, err
}
func (s *TimerLayerChannelStore) GroupSyncedChannelCount() (int64, error) {
start := timemodule.Now()
@@ -1920,6 +1956,22 @@ func (s *TimerLayerChannelStore) SetDeleteAt(channelID string, deleteAt int64, u
return err
}
func (s *TimerLayerChannelStore) SetShared(channelId string, shared bool) error {
start := timemodule.Now()
err := s.ChannelStore.SetShared(channelId, shared)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.SetShared", success, elapsed)
}
return err
}
func (s *TimerLayerChannelStore) Update(channel *model.Channel) (*model.Channel, error) {
start := timemodule.Now()
@@ -4796,6 +4848,22 @@ func (s *TimerLayerPostStore) GetPostsSince(options model.GetPostsSinceOptions,
return result, err
}
func (s *TimerLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error) {
start := timemodule.Now()
result, err := s.PostStore.GetPostsSinceForSync(options, allowFromCache)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetPostsSinceForSync", success, elapsed)
}
return result, err
}
func (s *TimerLayerPostStore) GetRepliesForExport(parentID string) ([]*model.ReplyForExport, error) {
start := timemodule.Now()
@@ -4812,10 +4880,10 @@ func (s *TimerLayerPostStore) GetRepliesForExport(parentID string) ([]*model.Rep
return result, err
}
func (s *TimerLayerPostStore) GetSingle(id string) (*model.Post, error) {
func (s *TimerLayerPostStore) GetSingle(id string, inclDeleted bool) (*model.Post, error) {
start := timemodule.Now()
result, err := s.PostStore.GetSingle(id)
result, err := s.PostStore.GetSingle(id, inclDeleted)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
@@ -5275,6 +5343,22 @@ func (s *TimerLayerReactionStore) GetForPost(postID string, allowFromCache bool)
return result, err
}
func (s *TimerLayerReactionStore) GetForPostSince(postId string, since int64, excludeRemoteId string, inclDeleted bool) ([]*model.Reaction, error) {
start := timemodule.Now()
result, err := s.ReactionStore.GetForPostSince(postId, since, excludeRemoteId, inclDeleted)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ReactionStore.GetForPostSince", success, elapsed)
}
return result, err
}
func (s *TimerLayerReactionStore) PermanentDeleteBatch(endTime int64, limit int64) (int64, error) {
start := timemodule.Now()
@@ -5307,6 +5391,118 @@ func (s *TimerLayerReactionStore) Save(reaction *model.Reaction) (*model.Reactio
return result, err
}
func (s *TimerLayerRemoteClusterStore) Delete(remoteClusterId string) (bool, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.Delete(remoteClusterId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.Delete", success, elapsed)
}
return result, err
}
func (s *TimerLayerRemoteClusterStore) Get(remoteClusterId string) (*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.Get(remoteClusterId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.Get", success, elapsed)
}
return result, err
}
func (s *TimerLayerRemoteClusterStore) GetAll(filter model.RemoteClusterQueryFilter) ([]*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.GetAll(filter)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.GetAll", success, elapsed)
}
return result, err
}
func (s *TimerLayerRemoteClusterStore) Save(rc *model.RemoteCluster) (*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.Save(rc)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.Save", success, elapsed)
}
return result, err
}
func (s *TimerLayerRemoteClusterStore) SetLastPingAt(remoteClusterId string) error {
start := timemodule.Now()
err := s.RemoteClusterStore.SetLastPingAt(remoteClusterId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.SetLastPingAt", success, elapsed)
}
return err
}
func (s *TimerLayerRemoteClusterStore) Update(rc *model.RemoteCluster) (*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.Update(rc)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.Update", success, elapsed)
}
return result, err
}
func (s *TimerLayerRemoteClusterStore) UpdateTopics(remoteClusterId string, topics string) (*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.RemoteClusterStore.UpdateTopics(remoteClusterId, topics)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("RemoteClusterStore.UpdateTopics", success, elapsed)
}
return result, err
}
func (s *TimerLayerRoleStore) AllChannelSchemeRoles() ([]*model.Role, error) {
start := timemodule.Now()
@@ -5850,6 +6046,390 @@ func (s *TimerLayerSessionStore) UpdateRoles(userId string, roles string) (strin
return result, err
}
func (s *TimerLayerSharedChannelStore) Delete(channelId string) (bool, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.Delete(channelId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.Delete", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) DeleteRemote(remoteId string) (bool, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.DeleteRemote(remoteId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.DeleteRemote", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) Get(channelId string) (*model.SharedChannel, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.Get(channelId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.Get", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetAll(offset int, limit int, opts model.SharedChannelFilterOpts) ([]*model.SharedChannel, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetAll(offset, limit, opts)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetAll", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetAllCount(opts model.SharedChannelFilterOpts) (int64, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetAllCount(opts)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetAllCount", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetAttachment(fileId string, remoteId string) (*model.SharedChannelAttachment, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetAttachment(fileId, remoteId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetAttachment", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetRemote(id string) (*model.SharedChannelRemote, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetRemote(id)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetRemote", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetRemoteByIds(channelId string, remoteId string) (*model.SharedChannelRemote, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetRemoteByIds(channelId, remoteId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetRemoteByIds", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetRemoteForUser(remoteId string, userId string) (*model.RemoteCluster, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetRemoteForUser(remoteId, userId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetRemoteForUser", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetRemotes(opts model.SharedChannelRemoteFilterOpts) ([]*model.SharedChannelRemote, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetRemotes(opts)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetRemotes", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetRemotesStatus(channelId string) ([]*model.SharedChannelRemoteStatus, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetRemotesStatus(channelId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetRemotesStatus", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) GetUser(userId string, remoteId string) (*model.SharedChannelUser, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.GetUser(userId, remoteId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetUser", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) HasChannel(channelID string) (bool, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.HasChannel(channelID)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.HasChannel", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) HasRemote(channelID string, remoteId string) (bool, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.HasRemote(channelID, remoteId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.HasRemote", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) Save(sc *model.SharedChannel) (*model.SharedChannel, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.Save(sc)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.Save", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) SaveAttachment(remote *model.SharedChannelAttachment) (*model.SharedChannelAttachment, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.SaveAttachment(remote)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.SaveAttachment", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) SaveRemote(remote *model.SharedChannelRemote) (*model.SharedChannelRemote, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.SaveRemote(remote)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.SaveRemote", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) SaveUser(remote *model.SharedChannelUser) (*model.SharedChannelUser, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.SaveUser(remote)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.SaveUser", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) Update(sc *model.SharedChannel) (*model.SharedChannel, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.Update(sc)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.Update", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) UpdateAttachmentLastSyncAt(id string, syncTime int64) error {
start := timemodule.Now()
err := s.SharedChannelStore.UpdateAttachmentLastSyncAt(id, syncTime)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateAttachmentLastSyncAt", success, elapsed)
}
return err
}
func (s *TimerLayerSharedChannelStore) UpdateRemote(remote *model.SharedChannelRemote) (*model.SharedChannelRemote, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.UpdateRemote(remote)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateRemote", success, elapsed)
}
return result, err
}
func (s *TimerLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
start := timemodule.Now()
err := s.SharedChannelStore.UpdateRemoteNextSyncAt(id, syncTime)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateRemoteNextSyncAt", success, elapsed)
}
return err
}
func (s *TimerLayerSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
start := timemodule.Now()
err := s.SharedChannelStore.UpdateUserLastSyncAt(id, syncTime)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateUserLastSyncAt", success, elapsed)
}
return err
}
func (s *TimerLayerSharedChannelStore) UpsertAttachment(remote *model.SharedChannelAttachment) (string, error) {
start := timemodule.Now()
result, err := s.SharedChannelStore.UpsertAttachment(remote)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpsertAttachment", success, elapsed)
}
return result, err
}
func (s *TimerLayerStatusStore) Get(userId string) (*model.Status, error) {
start := timemodule.Now()
@@ -9219,9 +9799,11 @@ func New(childStore store.Store, metrics einterfaces.MetricsInterface) *TimerLay
newStore.PreferenceStore = &TimerLayerPreferenceStore{PreferenceStore: childStore.Preference(), Root: &newStore}
newStore.ProductNoticesStore = &TimerLayerProductNoticesStore{ProductNoticesStore: childStore.ProductNotices(), Root: &newStore}
newStore.ReactionStore = &TimerLayerReactionStore{ReactionStore: childStore.Reaction(), Root: &newStore}
newStore.RemoteClusterStore = &TimerLayerRemoteClusterStore{RemoteClusterStore: childStore.RemoteCluster(), Root: &newStore}
newStore.RoleStore = &TimerLayerRoleStore{RoleStore: childStore.Role(), Root: &newStore}
newStore.SchemeStore = &TimerLayerSchemeStore{SchemeStore: childStore.Scheme(), Root: &newStore}
newStore.SessionStore = &TimerLayerSessionStore{SessionStore: childStore.Session(), Root: &newStore}
newStore.SharedChannelStore = &TimerLayerSharedChannelStore{SharedChannelStore: childStore.SharedChannel(), Root: &newStore}
newStore.StatusStore = &TimerLayerStatusStore{StatusStore: childStore.Status(), Root: &newStore}
newStore.SystemStore = &TimerLayerSystemStore{SystemStore: childStore.System(), Root: &newStore}
newStore.TeamStore = &TimerLayerTeamStore{TeamStore: childStore.Team(), Root: &newStore}