Skip to content

Commit

Permalink
Decouple structify from contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
lippserd committed Apr 25, 2024
1 parent f3670cc commit 28ad99b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
10 changes: 9 additions & 1 deletion pkg/icingadb/history/sla.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package history

import (
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/icingadb/types"
"github.com/icinga/icingadb/pkg/icingadb/v1/history"
"github.com/icinga/icingadb/pkg/redis"
"github.com/icinga/icingadb/pkg/structify"
"reflect"
)

var slaStateStructify = structify.MakeMapStructifier(reflect.TypeOf((*history.SlaHistoryState)(nil)).Elem(), "json")
var slaStateStructify = structify.MakeMapStructifier(
reflect.TypeOf((*history.SlaHistoryState)(nil)).Elem(),
"json",
func(a any) {
if initer, ok := a.(contracts.Initer); ok {
initer.Init()
}
})

func stateHistoryToSlaEntity(entry redis.XMessage) ([]history.UpserterEntity, error) {
slaStateInterface, err := slaStateStructify(entry.Values)
Expand Down
19 changes: 17 additions & 2 deletions pkg/icingadb/history/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package history
import (
"context"
"github.com/icinga/icingadb/pkg/com"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
v1types "github.com/icinga/icingadb/pkg/icingadb/v1"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1/history"
Expand Down Expand Up @@ -177,7 +178,14 @@ type stageFunc func(ctx context.Context, s Sync, key string, in <-chan redis.XMe
// For each history event it receives, it parses that event into a new instance of that entity type and writes it to
// the database. It writes exactly one entity to the database for each history event.
func writeOneEntityStage(structPtr interface{}) stageFunc {
structifier := structify.MakeMapStructifier(reflect.TypeOf(structPtr).Elem(), "json")
structifier := structify.MakeMapStructifier(
reflect.TypeOf(structPtr).Elem(),
"json",
func(a any) {
if initer, ok := a.(contracts.Initer); ok {
initer.Init()
}
})

return writeMultiEntityStage(func(entry redis.XMessage) ([]v1.UpserterEntity, error) {
ptr, err := structifier(entry.Values)
Expand Down Expand Up @@ -313,7 +321,14 @@ func userNotificationStage(ctx context.Context, s Sync, key string, in <-chan re
UserIds types.String `structify:"users_notified_ids"`
}

structifier := structify.MakeMapStructifier(reflect.TypeOf((*NotificationHistory)(nil)).Elem(), "structify")
structifier := structify.MakeMapStructifier(
reflect.TypeOf((*NotificationHistory)(nil)).Elem(),
"structify",
func(a any) {
if initer, ok := a.(contracts.Initer); ok {
initer.Init()
}
})

return writeMultiEntityStage(func(entry redis.XMessage) ([]v1.UpserterEntity, error) {
rawNotificationHistory, err := structifier(entry.Values)
Expand Down
19 changes: 17 additions & 2 deletions pkg/icingadb/runtime_updates.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/icinga/icingadb/pkg/com"
"github.com/icinga/icingadb/pkg/common"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/icinga/icingadb/pkg/database"
v1 "github.com/icinga/icingadb/pkg/icingadb/v1"
"github.com/icinga/icingadb/pkg/icingaredis/telemetry"
Expand Down Expand Up @@ -95,7 +96,14 @@ func (r *RuntimeUpdates) Sync(

g.Go(structifyStream(
ctx, updateMessages, upsertEntities, upsertedFifo, deleteIds, deletedFifo,
structify.MakeMapStructifier(reflect.TypeOf(s.Entity()).Elem(), "json"),
structify.MakeMapStructifier(
reflect.TypeOf(s.Entity()).Elem(),
"json",
func(a any) {
if initer, ok := a.(contracts.Initer); ok {
initer.Init()
}
}),
))

g.Go(func() error {
Expand Down Expand Up @@ -155,7 +163,14 @@ func (r *RuntimeUpdates) Sync(
updateMessagesByKey["icinga:"+strcase.Delimited(cv.Name(), ':')] = updateMessages
g.Go(structifyStream(
ctx, updateMessages, upsertEntities, nil, deleteIds, nil,
structify.MakeMapStructifier(reflect.TypeOf(cv.Entity()).Elem(), "json"),
structify.MakeMapStructifier(
reflect.TypeOf(cv.Entity()).Elem(),
"json",
func(a any) {
if initer, ok := a.(contracts.Initer); ok {
initer.Init()
}
}),
))

customvars, flatCustomvars, errs := v1.ExpandCustomvars(ctx, upsertEntities)
Expand Down
9 changes: 3 additions & 6 deletions pkg/structify/structify.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package structify
import (
"encoding"
"fmt"
"github.com/icinga/icingadb/pkg/contracts"
"github.com/pkg/errors"
"golang.org/x/exp/constraints"
"reflect"
Expand All @@ -27,17 +26,15 @@ type MapStructifier = func(map[string]interface{}) (interface{}, error)
// MakeMapStructifier builds a function which parses a map's string values into a new struct of type t
// and returns a pointer to it. tag specifies which tag connects struct fields to map keys.
// MakeMapStructifier panics if it detects an unsupported type (suitable for usage in init() or global vars).
func MakeMapStructifier(t reflect.Type, tag string) MapStructifier {
func MakeMapStructifier(t reflect.Type, tag string, initer func(any)) MapStructifier {
tree := buildStructTree(t, tag)

return func(kv map[string]interface{}) (interface{}, error) {
vPtr := reflect.New(t)
ptr := vPtr.Interface()

if initer, ok := ptr.(contracts.Initer); ok {
initer.Init()
if initer != nil {
initer(ptr)
}

vPtrElem := vPtr.Elem()
err := errors.Wrapf(structifyMapByTree(kv, tree, vPtrElem, vPtrElem, new([]int)), "can't structify map %#v by tree %#v", kv, tree)

Expand Down

0 comments on commit 28ad99b

Please sign in to comment.