mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-18 18:18:23 -05:00
Add metrics for mobile versions snapshots (#28191)
* Add metrics for mobile versions snapshots * Add notifications disabled and fix lint * Address feedback * Verify all references to JobTypeActiveUsers * Fix typos * Improve platform values * Add test and MySQL support
This commit is contained in:
parent
d45a54a8e9
commit
040838b056
17 changed files with 489 additions and 0 deletions
|
|
@ -175,6 +175,7 @@ func (a *App) SessionHasPermissionToReadJob(session model.Session, jobType strin
|
|||
model.JobTypeExportProcess,
|
||||
model.JobTypeExportDelete,
|
||||
model.JobTypeCloud,
|
||||
model.JobTypeMobileSessionMetadata,
|
||||
model.JobTypeExtractContent:
|
||||
return a.SessionHasPermissionTo(session, model.PermissionReadJobs), model.PermissionReadJobs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import (
|
|||
"github.com/mattermost/mattermost/server/v8/channels/jobs/last_accessible_file"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/last_accessible_post"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/migrations"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/mobile_session_metadata"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/notify_admin"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/plugins"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs/post_persistent_notifications"
|
||||
|
|
@ -1565,6 +1566,12 @@ func (s *Server) initJobs() {
|
|||
active_users.MakeScheduler(s.Jobs),
|
||||
)
|
||||
|
||||
s.Jobs.RegisterJobType(
|
||||
model.JobTypeMobileSessionMetadata,
|
||||
mobile_session_metadata.MakeWorker(s.Jobs, s.Store(), func() einterfaces.MetricsInterface { return s.GetMetrics() }),
|
||||
mobile_session_metadata.MakeScheduler(s.Jobs),
|
||||
)
|
||||
|
||||
s.Jobs.RegisterJobType(
|
||||
model.JobTypeResendInvitationEmail,
|
||||
resend_invitation_email.MakeWorker(s.Jobs, New(ServerConnector(s.Channels())), s.Store(), s.telemetryService),
|
||||
|
|
|
|||
20
server/channels/jobs/mobile_session_metadata/scheduler.go
Normal file
20
server/channels/jobs/mobile_session_metadata/scheduler.go
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mobile_session_metadata
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs"
|
||||
)
|
||||
|
||||
const schedFreq = 24 * time.Hour
|
||||
|
||||
func MakeScheduler(jobServer *jobs.JobServer) *jobs.PeriodicScheduler {
|
||||
isEnabled := func(cfg *model.Config) bool {
|
||||
return *cfg.MetricsSettings.EnableClientMetrics
|
||||
}
|
||||
return jobs.NewPeriodicScheduler(jobServer, model.JobTypeMobileSessionMetadata, schedFreq, isEnabled)
|
||||
}
|
||||
42
server/channels/jobs/mobile_session_metadata/worker.go
Normal file
42
server/channels/jobs/mobile_session_metadata/worker.go
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package mobile_session_metadata
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/jobs"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
"github.com/mattermost/mattermost/server/v8/einterfaces"
|
||||
)
|
||||
|
||||
func MakeWorker(jobServer *jobs.JobServer, store store.Store, getMetrics func() einterfaces.MetricsInterface) *jobs.SimpleWorker {
|
||||
const workerName = "MobileSessionMetadata"
|
||||
|
||||
isEnabled := func(cfg *model.Config) bool {
|
||||
return *cfg.MetricsSettings.EnableClientMetrics
|
||||
}
|
||||
execute := func(logger mlog.LoggerIFace, job *model.Job) error {
|
||||
defer jobServer.HandleJobPanic(logger, job)
|
||||
|
||||
metrics := getMetrics()
|
||||
if metrics == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
versions, err := store.Session().GetMobileSessionMetadata()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metrics.ClearMobileClientSessionMetadata()
|
||||
for _, v := range versions {
|
||||
metrics.ObserveMobileClientSessionMetadata(v.Version, v.Platform, v.Count, v.NotificationDisabled)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
worker := jobs.NewSimpleWorker(workerName, jobServer, execute, isEnabled)
|
||||
return worker
|
||||
}
|
||||
|
|
@ -8710,6 +8710,24 @@ func (s *OpenTracingLayerSessionStore) GetLRUSessions(c request.CTX, userID stri
|
|||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSessionStore) GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetMobileSessionMetadata")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SessionStore.GetMobileSessionMetadata()
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSessionStore) GetSessions(c request.CTX, userID string) ([]*model.Session, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetSessions")
|
||||
|
|
|
|||
|
|
@ -9938,6 +9938,27 @@ func (s *RetryLayerSessionStore) GetLRUSessions(c request.CTX, userID string, li
|
|||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSessionStore) GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SessionStore.GetMobileSessionMetadata()
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
timepkg.Sleep(100 * timepkg.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSessionStore) GetSessions(c request.CTX, userID string) ([]*model.Session, error) {
|
||||
|
||||
tries := 0
|
||||
|
|
|
|||
|
|
@ -164,6 +164,38 @@ func (me SqlSessionStore) GetSessionsWithActiveDeviceIds(userId string) ([]*mode
|
|||
return sessions, nil
|
||||
}
|
||||
|
||||
func (me SqlSessionStore) GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error) {
|
||||
versionProp := model.SessionPropMobileVersion
|
||||
notificationDisabledProp := model.SessionPropDeviceNotificationDisabled
|
||||
platformQuery := "NULLIF(SPLIT_PART(deviceid, ':', 1), '')"
|
||||
if me.DriverName() == model.DatabaseDriverMysql {
|
||||
versionProp = "$." + versionProp
|
||||
notificationDisabledProp = "$." + notificationDisabledProp
|
||||
platformQuery = "NULLIF(SUBSTRING_INDEX(deviceid, ':', 1), deviceid)"
|
||||
}
|
||||
|
||||
query, args, err := me.getQueryBuilder().
|
||||
Select(fmt.Sprintf(
|
||||
"COUNT(userid) AS Count, COALESCE(%s,'N/A') AS Platform, COALESCE(props->>'%s','N/A') AS Version, COALESCE(props->>'%s','false') as NotificationDisabled",
|
||||
platformQuery,
|
||||
versionProp,
|
||||
notificationDisabledProp,
|
||||
)).
|
||||
From("Sessions").
|
||||
GroupBy("Platform", "Version", "NotificationDisabled").
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "sessions_tosql")
|
||||
}
|
||||
|
||||
versions := []*model.MobileSessionMetadata{}
|
||||
err = me.GetReplicaX().Select(&versions, query, args...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed get mobile session metadata")
|
||||
}
|
||||
return versions, nil
|
||||
}
|
||||
|
||||
func (me SqlSessionStore) GetSessionsExpired(thresholdMillis int64, mobileOnly bool, unnotifiedOnly bool) ([]*model.Session, error) {
|
||||
now := model.GetMillis()
|
||||
builder := me.getQueryBuilder().
|
||||
|
|
|
|||
|
|
@ -503,6 +503,7 @@ type SessionStore interface {
|
|||
Save(c request.CTX, session *model.Session) (*model.Session, error)
|
||||
GetSessions(c request.CTX, userID string) ([]*model.Session, error)
|
||||
GetLRUSessions(c request.CTX, userID string, limit uint64, offset uint64) ([]*model.Session, error)
|
||||
GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error)
|
||||
GetSessionsWithActiveDeviceIds(userID string) ([]*model.Session, error)
|
||||
GetSessionsExpired(thresholdMillis int64, mobileOnly bool, unnotifiedOnly bool) ([]*model.Session, error)
|
||||
UpdateExpiredNotify(sessionid string, notified bool) error
|
||||
|
|
|
|||
|
|
@ -121,6 +121,36 @@ func (_m *SessionStore) GetLRUSessions(c request.CTX, userID string, limit uint6
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// GetMobileSessionMetadata provides a mock function with given fields:
|
||||
func (_m *SessionStore) GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetMobileSessionMetadata")
|
||||
}
|
||||
|
||||
var r0 []*model.MobileSessionMetadata
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() ([]*model.MobileSessionMetadata, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() []*model.MobileSessionMetadata); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.MobileSessionMetadata)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetSessions provides a mock function with given fields: c, userID
|
||||
func (_m *SessionStore) GetSessions(c request.CTX, userID string) ([]*model.Session, error) {
|
||||
ret := _m.Called(c, userID)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func TestSessionStore(t *testing.T, rctx request.CTX, ss store.Store) {
|
|||
t.Run("GetSessionsExpired", func(t *testing.T) { testGetSessionsExpired(t, rctx, ss) })
|
||||
t.Run("UpdateExpiredNotify", func(t *testing.T) { testUpdateExpiredNotify(t, rctx, ss) })
|
||||
t.Run("GetLRUSessions", func(t *testing.T) { testGetLRUSessions(t, rctx, ss) })
|
||||
t.Run("GetMobileSessionMetadata", func(t *testing.T) { testGetMobileSessionMetadata(t, rctx, ss) })
|
||||
}
|
||||
|
||||
func testSessionStoreSave(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
|
|
@ -456,3 +457,84 @@ func testGetLRUSessions(t *testing.T, rctx request.CTX, ss store.Store) {
|
|||
require.Equal(t, s2.Id, sessions[1].Id)
|
||||
require.Equal(t, s1.Id, sessions[2].Id)
|
||||
}
|
||||
|
||||
func testGetMobileSessionMetadata(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
userId1 := model.NewId()
|
||||
userId2 := model.NewId()
|
||||
userId3 := model.NewId()
|
||||
userId4 := model.NewId()
|
||||
userId5 := model.NewId()
|
||||
|
||||
// Clear existing sessions.
|
||||
err := ss.Session().RemoveAllSessions()
|
||||
require.NoError(t, err)
|
||||
|
||||
s1 := &model.Session{}
|
||||
s1.UserId = userId1
|
||||
s1.ExpiresAt = model.GetMillis() + 10000
|
||||
|
||||
_, err = ss.Session().Save(rctx, s1)
|
||||
require.NoError(t, err)
|
||||
|
||||
s2 := &model.Session{}
|
||||
s2.UserId = userId2
|
||||
s2.DeviceId = "android:" + model.NewId()
|
||||
s2.ExpiresAt = model.GetMillis() + 10000
|
||||
s2.Props = model.StringMap{
|
||||
model.SessionPropDeviceNotificationDisabled: "false",
|
||||
model.SessionPropMobileVersion: "1.2.3",
|
||||
}
|
||||
|
||||
_, err = ss.Session().Save(rctx, s2)
|
||||
require.NoError(t, err)
|
||||
|
||||
s3 := &model.Session{}
|
||||
s3.UserId = userId3
|
||||
s3.DeviceId = "ios:" + model.NewId()
|
||||
s3.ExpiresAt = model.GetMillis() + 10000
|
||||
s3.Props = model.StringMap{
|
||||
model.SessionPropDeviceNotificationDisabled: "true",
|
||||
model.SessionPropMobileVersion: "1.2.3",
|
||||
}
|
||||
|
||||
_, err = ss.Session().Save(rctx, s3)
|
||||
require.NoError(t, err)
|
||||
|
||||
s4 := &model.Session{}
|
||||
s4.UserId = userId4
|
||||
s4.DeviceId = "android:" + model.NewId()
|
||||
s4.ExpiresAt = model.GetMillis() + 10000
|
||||
s4.Props = model.StringMap{
|
||||
model.SessionPropDeviceNotificationDisabled: "true",
|
||||
model.SessionPropMobileVersion: "3.2.1",
|
||||
}
|
||||
|
||||
_, err = ss.Session().Save(rctx, s4)
|
||||
require.NoError(t, err)
|
||||
|
||||
s5 := &model.Session{}
|
||||
s5.UserId = userId5
|
||||
s5.DeviceId = "android:" + model.NewId()
|
||||
s5.ExpiresAt = model.GetMillis() + 10000
|
||||
s5.Props = model.StringMap{
|
||||
model.SessionPropDeviceNotificationDisabled: "true",
|
||||
model.SessionPropMobileVersion: "3.2.1",
|
||||
}
|
||||
|
||||
_, err = ss.Session().Save(rctx, s5)
|
||||
require.NoError(t, err)
|
||||
|
||||
metadata, err := ss.Session().GetMobileSessionMetadata()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, metadata, 4)
|
||||
found := false
|
||||
for _, d := range metadata {
|
||||
if d.NotificationDisabled == "true" &&
|
||||
d.Platform == "android" &&
|
||||
d.Version == "3.2.1" {
|
||||
found = true
|
||||
require.Equal(t, float64(2), d.Count)
|
||||
}
|
||||
}
|
||||
require.True(t, found)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7849,6 +7849,22 @@ func (s *TimerLayerSessionStore) GetLRUSessions(c request.CTX, userID string, li
|
|||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSessionStore) GetMobileSessionMetadata() ([]*model.MobileSessionMetadata, error) {
|
||||
start := time.Now()
|
||||
|
||||
result, err := s.SessionStore.GetMobileSessionMetadata()
|
||||
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SessionStore.GetMobileSessionMetadata", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSessionStore) GetSessions(c request.CTX, userID string) ([]*model.Session, error) {
|
||||
start := time.Now()
|
||||
|
||||
|
|
|
|||
|
|
@ -118,4 +118,6 @@ type MetricsInterface interface {
|
|||
ObserveMobileClientLoadDuration(platform string, elapsed float64)
|
||||
ObserveMobileClientChannelSwitchDuration(platform string, elapsed float64)
|
||||
ObserveMobileClientTeamSwitchDuration(platform string, elapsed float64)
|
||||
ClearMobileClientSessionMetadata()
|
||||
ObserveMobileClientSessionMetadata(version string, platform string, value float64, notificationDisabled string)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ func (_m *MetricsInterface) AddMemCacheMissCounter(cacheName string, amount floa
|
|||
_m.Called(cacheName, amount)
|
||||
}
|
||||
|
||||
// ClearMobileClientSessionMetadata provides a mock function with given fields:
|
||||
func (_m *MetricsInterface) ClearMobileClientSessionMetadata() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// DecrementHTTPWebSockets provides a mock function with given fields: originClient
|
||||
func (_m *MetricsInterface) DecrementHTTPWebSockets(originClient string) {
|
||||
_m.Called(originClient)
|
||||
|
|
@ -373,6 +378,11 @@ func (_m *MetricsInterface) ObserveMobileClientLoadDuration(platform string, ela
|
|||
_m.Called(platform, elapsed)
|
||||
}
|
||||
|
||||
// ObserveMobileClientSessionMetadata provides a mock function with given fields: version, platform, value, notificationDisabled
|
||||
func (_m *MetricsInterface) ObserveMobileClientSessionMetadata(version string, platform string, value float64, notificationDisabled string) {
|
||||
_m.Called(version, platform, value, notificationDisabled)
|
||||
}
|
||||
|
||||
// ObserveMobileClientTeamSwitchDuration provides a mock function with given fields: platform, elapsed
|
||||
func (_m *MetricsInterface) ObserveMobileClientTeamSwitchDuration(platform string, elapsed float64) {
|
||||
_m.Called(platform, elapsed)
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ type MetricsInterfaceImpl struct {
|
|||
MobileClientLoadDuration *prometheus.HistogramVec
|
||||
MobileClientChannelSwitchDuration *prometheus.HistogramVec
|
||||
MobileClientTeamSwitchDuration *prometheus.HistogramVec
|
||||
MobileClientSessionMetadataGauge *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -1335,6 +1336,17 @@ func New(ps *platform.PlatformService, driver, dataSource string) *MetricsInterf
|
|||
)
|
||||
m.Registry.MustRegister(m.MobileClientTeamSwitchDuration)
|
||||
|
||||
m.MobileClientSessionMetadataGauge = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: MetricsNamespace,
|
||||
Subsystem: MetricsSubsystemClientsMobileApp,
|
||||
Name: "mobile_session_metadata",
|
||||
Help: "The number of mobile sessions in each version, platform and whether they have the notifications disabled",
|
||||
},
|
||||
[]string{"version", "platform", "notifications_disabled"},
|
||||
)
|
||||
m.Registry.MustRegister(m.MobileClientSessionMetadataGauge)
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
@ -1850,6 +1862,14 @@ func (mi *MetricsInterfaceImpl) ObserveMobileClientTeamSwitchDuration(platform s
|
|||
mi.MobileClientTeamSwitchDuration.With(prometheus.Labels{"platform": platform}).Observe(elapsed)
|
||||
}
|
||||
|
||||
func (mi *MetricsInterfaceImpl) ObserveMobileClientSessionMetadata(version string, platform string, value float64, notificationDisabled string) {
|
||||
mi.MobileClientSessionMetadataGauge.With(prometheus.Labels{"version": version, "platform": platform, "notifications_disabled": notificationDisabled}).Set(value)
|
||||
}
|
||||
|
||||
func (mi *MetricsInterfaceImpl) ClearMobileClientSessionMetadata() {
|
||||
mi.MobileClientSessionMetadataGauge.Reset()
|
||||
}
|
||||
|
||||
func extractDBCluster(driver, connectionString string) (string, error) {
|
||||
host, err := extractHost(driver, connectionString)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ const (
|
|||
JobTypeDeleteOrphanDraftsMigration = "delete_orphan_drafts_migration"
|
||||
JobTypeExportUsersToCSV = "export_users_to_csv"
|
||||
JobTypeDeleteDmsPreferencesMigration = "delete_dms_preferences_migration"
|
||||
JobTypeMobileSessionMetadata = "mobile_session_metadata"
|
||||
|
||||
JobStatusPending = "pending"
|
||||
JobStatusInProgress = "in_progress"
|
||||
|
|
@ -72,6 +73,7 @@ var AllJobTypes = [...]string{
|
|||
JobTypeLastAccessibleFile,
|
||||
JobTypeCleanupDesktopTokens,
|
||||
JobTypeRefreshPostStats,
|
||||
JobTypeMobileSessionMetadata,
|
||||
}
|
||||
|
||||
type Job struct {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ const (
|
|||
//msgp:tuple StringMap
|
||||
type StringMap map[string]string
|
||||
|
||||
type MobileSessionMetadata struct {
|
||||
Version string
|
||||
Platform string
|
||||
Count float64
|
||||
NotificationDisabled string
|
||||
}
|
||||
|
||||
// Session contains the user session details.
|
||||
// This struct's serializer methods are auto-generated. If a new field is added/removed,
|
||||
// please run make gen-serialized.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,184 @@ import (
|
|||
"github.com/tinylib/msgp/msgp"
|
||||
)
|
||||
|
||||
// DecodeMsg implements msgp.Decodable
|
||||
func (z *MobileSessionMetadata) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zb0001 uint32
|
||||
zb0001, err = dc.ReadMapHeader()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
for zb0001 > 0 {
|
||||
zb0001--
|
||||
field, err = dc.ReadMapKeyPtr()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "Version":
|
||||
z.Version, err = dc.ReadString()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Version")
|
||||
return
|
||||
}
|
||||
case "Platform":
|
||||
z.Platform, err = dc.ReadString()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Platform")
|
||||
return
|
||||
}
|
||||
case "Count":
|
||||
z.Count, err = dc.ReadFloat64()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Count")
|
||||
return
|
||||
}
|
||||
case "NotificationDisabled":
|
||||
z.NotificationDisabled, err = dc.ReadString()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "NotificationDisabled")
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = dc.Skip()
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EncodeMsg implements msgp.Encodable
|
||||
func (z *MobileSessionMetadata) EncodeMsg(en *msgp.Writer) (err error) {
|
||||
// map header, size 4
|
||||
// write "Version"
|
||||
err = en.Append(0x84, 0xa7, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = en.WriteString(z.Version)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Version")
|
||||
return
|
||||
}
|
||||
// write "Platform"
|
||||
err = en.Append(0xa8, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = en.WriteString(z.Platform)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Platform")
|
||||
return
|
||||
}
|
||||
// write "Count"
|
||||
err = en.Append(0xa5, 0x43, 0x6f, 0x75, 0x6e, 0x74)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = en.WriteFloat64(z.Count)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Count")
|
||||
return
|
||||
}
|
||||
// write "NotificationDisabled"
|
||||
err = en.Append(0xb4, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = en.WriteString(z.NotificationDisabled)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "NotificationDisabled")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MarshalMsg implements msgp.Marshaler
|
||||
func (z *MobileSessionMetadata) MarshalMsg(b []byte) (o []byte, err error) {
|
||||
o = msgp.Require(b, z.Msgsize())
|
||||
// map header, size 4
|
||||
// string "Version"
|
||||
o = append(o, 0x84, 0xa7, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e)
|
||||
o = msgp.AppendString(o, z.Version)
|
||||
// string "Platform"
|
||||
o = append(o, 0xa8, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d)
|
||||
o = msgp.AppendString(o, z.Platform)
|
||||
// string "Count"
|
||||
o = append(o, 0xa5, 0x43, 0x6f, 0x75, 0x6e, 0x74)
|
||||
o = msgp.AppendFloat64(o, z.Count)
|
||||
// string "NotificationDisabled"
|
||||
o = append(o, 0xb4, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64)
|
||||
o = msgp.AppendString(o, z.NotificationDisabled)
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalMsg implements msgp.Unmarshaler
|
||||
func (z *MobileSessionMetadata) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
||||
var field []byte
|
||||
_ = field
|
||||
var zb0001 uint32
|
||||
zb0001, bts, err = msgp.ReadMapHeaderBytes(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
for zb0001 > 0 {
|
||||
zb0001--
|
||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
switch msgp.UnsafeString(field) {
|
||||
case "Version":
|
||||
z.Version, bts, err = msgp.ReadStringBytes(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Version")
|
||||
return
|
||||
}
|
||||
case "Platform":
|
||||
z.Platform, bts, err = msgp.ReadStringBytes(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Platform")
|
||||
return
|
||||
}
|
||||
case "Count":
|
||||
z.Count, bts, err = msgp.ReadFloat64Bytes(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "Count")
|
||||
return
|
||||
}
|
||||
case "NotificationDisabled":
|
||||
z.NotificationDisabled, bts, err = msgp.ReadStringBytes(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err, "NotificationDisabled")
|
||||
return
|
||||
}
|
||||
default:
|
||||
bts, err = msgp.Skip(bts)
|
||||
if err != nil {
|
||||
err = msgp.WrapError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
o = bts
|
||||
return
|
||||
}
|
||||
|
||||
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
||||
func (z *MobileSessionMetadata) Msgsize() (s int) {
|
||||
s = 1 + 8 + msgp.StringPrefixSize + len(z.Version) + 9 + msgp.StringPrefixSize + len(z.Platform) + 6 + msgp.Float64Size + 21 + msgp.StringPrefixSize + len(z.NotificationDisabled)
|
||||
return
|
||||
}
|
||||
|
||||
// DecodeMsg implements msgp.Decodable
|
||||
func (z *Session) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||
var zb0001 uint32
|
||||
|
|
|
|||
Loading…
Reference in a new issue