1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

fix: resolve project labels before resolving aliases (resolve #222)

This commit is contained in:
Ferdinand Mütsch 2021-08-06 17:07:36 +02:00
parent 533b5d62fc
commit 93bdb48d95
4 changed files with 547 additions and 500 deletions

View File

@ -10,9 +10,14 @@ type ApplicationEvent struct {
const ( const (
TopicUser = "user.*" TopicUser = "user.*"
TopicHeartbeat = "heartbeat.*" TopicHeartbeat = "heartbeat.*"
TopicProjectLabel = "project_label.*"
EventUserUpdate = "user.update" EventUserUpdate = "user.update"
EventHeartbeatCreate = "heartbeat.create" EventHeartbeatCreate = "heartbeat.create"
EventProjectLabelCreate = "project_label.create"
EventProjectLabelDelete = "project_label.delete"
FieldPayload = "payload" FieldPayload = "payload"
FieldUser = "user"
FieldUserId = "user.id"
) )
var eventHub *hub.Hub var eventHub *hub.Hub

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ package services
import ( import (
"errors" "errors"
"github.com/leandro-lugaresi/hub"
"github.com/muety/wakapi/config" "github.com/muety/wakapi/config"
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
"github.com/muety/wakapi/repositories" "github.com/muety/wakapi/repositories"
@ -12,12 +13,14 @@ import (
type ProjectLabelService struct { type ProjectLabelService struct {
config *config.Config config *config.Config
cache *cache.Cache cache *cache.Cache
eventBus *hub.Hub
repository repositories.IProjectLabelRepository repository repositories.IProjectLabelRepository
} }
func NewProjectLabelService(projectLabelRepository repositories.IProjectLabelRepository) *ProjectLabelService { func NewProjectLabelService(projectLabelRepository repositories.IProjectLabelRepository) *ProjectLabelService {
return &ProjectLabelService{ return &ProjectLabelService{
config: config.Get(), config: config.Get(),
eventBus: config.EventBus(),
repository: projectLabelRepository, repository: projectLabelRepository,
cache: cache.New(24*time.Hour, 24*time.Hour), cache: cache.New(24*time.Hour, 24*time.Hour),
} }
@ -65,6 +68,7 @@ func (srv *ProjectLabelService) Create(label *models.ProjectLabel) (*models.Proj
} }
srv.cache.Delete(result.UserID) srv.cache.Delete(result.UserID)
srv.notifyUpdate(label, false)
return result, nil return result, nil
} }
@ -74,5 +78,17 @@ func (srv *ProjectLabelService) Delete(label *models.ProjectLabel) error {
} }
err := srv.repository.Delete(label.ID) err := srv.repository.Delete(label.ID)
srv.cache.Delete(label.UserID) srv.cache.Delete(label.UserID)
srv.notifyUpdate(label, true)
return err return err
} }
func (srv *ProjectLabelService) notifyUpdate(label *models.ProjectLabel, isDelete bool) {
name := config.EventProjectLabelCreate
if isDelete {
name = config.EventProjectLabelDelete
}
srv.eventBus.Publish(hub.Message{
Name: name,
Fields: map[string]interface{}{config.FieldPayload: label, config.FieldUserId: label.UserID},
})
}

View File

@ -2,7 +2,9 @@ package services
import ( import (
"errors" "errors"
"fmt"
"github.com/emvi/logbuch" "github.com/emvi/logbuch"
"github.com/leandro-lugaresi/hub"
"github.com/muety/wakapi/config" "github.com/muety/wakapi/config"
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
"github.com/muety/wakapi/repositories" "github.com/muety/wakapi/repositories"
@ -18,6 +20,7 @@ const HeartbeatDiffThreshold = 2 * time.Minute
type SummaryService struct { type SummaryService struct {
config *config.Config config *config.Config
cache *cache.Cache cache *cache.Cache
eventBus *hub.Hub
repository repositories.ISummaryRepository repository repositories.ISummaryRepository
heartbeatService IHeartbeatService heartbeatService IHeartbeatService
aliasService IAliasService aliasService IAliasService
@ -27,18 +30,34 @@ type SummaryService struct {
type SummaryRetriever func(f, t time.Time, u *models.User) (*models.Summary, error) type SummaryRetriever func(f, t time.Time, u *models.User) (*models.Summary, error)
func NewSummaryService(summaryRepo repositories.ISummaryRepository, heartbeatService IHeartbeatService, aliasService IAliasService, projectLabelService IProjectLabelService) *SummaryService { func NewSummaryService(summaryRepo repositories.ISummaryRepository, heartbeatService IHeartbeatService, aliasService IAliasService, projectLabelService IProjectLabelService) *SummaryService {
return &SummaryService{ srv := &SummaryService{
config: config.Get(), config: config.Get(),
cache: cache.New(24*time.Hour, 24*time.Hour), cache: cache.New(24*time.Hour, 24*time.Hour),
eventBus: config.EventBus(),
repository: summaryRepo, repository: summaryRepo,
heartbeatService: heartbeatService, heartbeatService: heartbeatService,
aliasService: aliasService, aliasService: aliasService,
projectLabelService: projectLabelService, projectLabelService: projectLabelService,
} }
sub1 := srv.eventBus.Subscribe(0, config.TopicProjectLabel)
go func(sub *hub.Subscription) {
for m := range sub.Receiver {
userId := m.Fields[config.FieldUserId].(string)
for key := range srv.cache.Items() {
if strings.HasSuffix(key, fmt.Sprintf("__%s__--aliased", userId)) {
srv.cache.Delete(key)
}
}
}
}(&sub1)
return srv
} }
// Public summary generation methods // Public summary generation methods
// Aliased retrieves or computes a new summary based on the given SummaryRetriever and augments it with entity aliases and project labels
func (srv *SummaryService) Aliased(from, to time.Time, user *models.User, f SummaryRetriever, skipCache bool) (*models.Summary, error) { func (srv *SummaryService) Aliased(from, to time.Time, user *models.User, f SummaryRetriever, skipCache bool) (*models.Summary, error) {
// Check cache // Check cache
cacheKey := srv.getHash(from.String(), to.String(), user.ID, "--aliased") cacheKey := srv.getHash(from.String(), to.String(), user.ID, "--aliased")
@ -65,6 +84,7 @@ func (srv *SummaryService) Aliased(from, to time.Time, user *models.User, f Summ
// Post-process summary and cache it // Post-process summary and cache it
summary := s.WithResolvedAliases(resolve) summary := s.WithResolvedAliases(resolve)
summary = srv.withProjectLabels(summary)
summary.FillBy(models.SummaryProject, models.SummaryLabel) // first fill up labels from projects summary.FillBy(models.SummaryProject, models.SummaryLabel) // first fill up labels from projects
summary.FillMissing() // then, full up types which are entirely missing summary.FillMissing() // then, full up types which are entirely missing
@ -94,7 +114,6 @@ func (srv *SummaryService) Retrieve(from, to time.Time, user *models.User) (*mod
if err != nil { if err != nil {
return nil, err return nil, err
} }
summary = srv.withProjectLabels(summary)
return summary.Sorted(), nil return summary.Sorted(), nil
} }
@ -154,7 +173,6 @@ func (srv *SummaryService) Summarize(from, to time.Time, user *models.User) (*mo
OperatingSystems: osItems, OperatingSystems: osItems,
Machines: machineItems, Machines: machineItems,
} }
summary = srv.withProjectLabels(summary)
return summary.Sorted(), nil return summary.Sorted(), nil
} }