Skip to content

Commit

Permalink
feat: proposal for collecting community metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
MishkaRogachev committed Jul 25, 2023
1 parent 14483da commit 67a635b
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 0 deletions.
26 changes: 26 additions & 0 deletions protocol/messenger_community_metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package protocol

import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/requests"
)

type CommunityMetricsResponse struct {
Type requests.CommunityMetricsRequestType `json:"type"`
CommunityID types.HexBytes `json:"communityId"`
Entries map[uint64]int32 `json:"entries"`
}

func (m *Messenger) CollectCommunityMetrics(request *requests.CommunityMetricsRequest) (*CommunityMetricsResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}

response := &CommunityMetricsResponse{
Type: request.Type,
CommunityID: request.CommunityID,
// TODO: collect entries
}

return response, nil
}
30 changes: 30 additions & 0 deletions protocol/messenger_community_metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package protocol

import (
"testing"

"github.com/status-im/status-go/protocol/requests"
"github.com/stretchr/testify/suite"
)

func TestMessengerCommunityMetricsSuite(t *testing.T) {
suite.Run(t, new(MessengerCommunityMetricsSuite))
}

type MessengerCommunityMetricsSuite struct {
MessengerBaseTestSuite
}

func (s *MessengerCommunityMetricsSuite) TestCollectCommunityMessageMetrics() {
request := &requests.CommunityMetricsRequest{
CommunityID: []byte("0x654321"),
Type: requests.CommunityMetricsRequestMessages,
StartTimestamp: 1690279200,
EndTimestamp: 1690282800, // one hour
MaxCount: 10,
}
// Send contact request
resp, err := s.m.CollectCommunityMetrics(request)
s.Require().NoError(err)
s.Require().NotNil(resp)
}
65 changes: 65 additions & 0 deletions protocol/persistence_metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package protocol

import (
"context"
"database/sql"
)

func (db sqlitePersistence) fetchMessagesCountForPeriod(tx *sql.Tx, chatID string, startTimestamp uint64, endTimestamp uint64) (int, error) {
var result int
err := tx.QueryRow(`
SELECT COUNT(*) FROM user_messages
WHERE local_chat_id = ? AND
timestamp >= ? AND
timestamp <= ?`,
chatID,
startTimestamp,
endTimestamp).Scan(&result)
if err != nil {
return 0, err
}
return result, nil
}

func (db sqlitePersistence) FetchMessagesCountForPeriod(chatID string, startTimestamp uint64, endTimestamp uint64) (int, error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return 0, err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()

return db.fetchMessagesCountForPeriod(tx, chatID, startTimestamp, endTimestamp)
}

func (db sqlitePersistence) FetchMessagesCountSequenceForPeriod(chatID string, startTimestamp uint64, endTimestamp uint64, timestampStep uint64) ([]int, error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return []int{}, err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
// don't shadow original error
_ = tx.Rollback()
}()

var sequence []int
for i := startTimestamp; i <= endTimestamp; i += timestampStep {
count, err := db.fetchMessagesCountForPeriod(tx, chatID, startTimestamp, endTimestamp)
if err != nil {
return []int{}, err
}

sequence = append(sequence, count)
}
return sequence, nil
}
1 change: 1 addition & 0 deletions protocol/persistence_metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package protocol
42 changes: 42 additions & 0 deletions protocol/requests/community_metrics_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package requests

import (
"errors"

"github.com/status-im/status-go/eth-node/types"
)

var ErrNoCommunityId = errors.New("community metrics request has no community id")
var ErrInvalidTimeInterval = errors.New("community metrics request invalid time interval")
var ErrInvalidMaxCount = errors.New("community metrics request max count should be gratear than zero")

type CommunityMetricsRequestType uint

const (
CommunityMetricsRequestMessages CommunityMetricsRequestType = iota + 1
CommunityMetricsRequestMembers
CommunityMetricsRequestControlNodeUptime
)

type CommunityMetricsRequest struct {
CommunityID types.HexBytes `json:"communityId"`
Type CommunityMetricsRequestType `json:"type"`
StartTimestamp uint64 `json:"startTimestamp"`
EndTimestamp uint64 `json:"endTimestamp"`
MaxCount uint `json:"maxCount"`
}

func (r *CommunityMetricsRequest) Validate() error {
if len(r.CommunityID) == 0 {
return ErrNoCommunityId
}

if r.StartTimestamp == 0 || r.EndTimestamp == 0 || r.StartTimestamp >= r.EndTimestamp {
return ErrInvalidTimeInterval
}

if r.MaxCount < 1 {
return ErrInvalidMaxCount
}
return nil
}
4 changes: 4 additions & 0 deletions services/ext/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,10 @@ func (api *PublicAPI) CheckAllCommunityChannelsPermissions(request *requests.Che
return api.service.messenger.CheckAllCommunityChannelsPermissions(request)
}

func (api *PublicAPI) CollectCommunityMetrics(request *requests.CommunityMetricsRequest) (*protocol.CommunityMetricsResponse, error) {
return api.service.messenger.CollectCommunityMetrics(request)
}

func (api *PublicAPI) ShareCommunityURLWithChatKey(communityID types.HexBytes) (string, error) {
return api.service.messenger.ShareCommunityURLWithChatKey(communityID)
}
Expand Down

0 comments on commit 67a635b

Please sign in to comment.