Skip to content

Commit

Permalink
BITS0000: Update all the select/trim/top/skip code to properly handle…
Browse files Browse the repository at this point in the history
… read-only return values.

Change-Id: I25d2165b2665543af4253039ca42782faaef1712
  • Loading branch information
superchalupa committed Feb 6, 2019
1 parent 504c8e2 commit 147c130
Show file tree
Hide file tree
Showing 9 changed files with 427 additions and 319 deletions.
4 changes: 4 additions & 0 deletions scripts/replay-events.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ fi
tmpfile=$(mktemp ./TEMP-XXXXXX)
trap "rm -f $tmpfile" EXIT

events_replayed=0
for file in "$@"
do
while read -u 5 line ; do
echo "$line" > $tmpfile

$CURLCMD --fail -f $BASE/api/Event%3AInject -d @$tmpfile

events_replayed=$(( events_replayed + 1 ))
echo "REPLAYED EVENTS: $events_replayed"

if [ -n "$singlestep" ]; then read -p "Paused" pause; fi

Expand Down
54 changes: 22 additions & 32 deletions src/dell-ec/instantiate-helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,38 +80,28 @@ func AddECInstantiate(l log.Logger, instantiateSvc *testaggregate.Service) {
return true, nil
})

MakeMaker(l, "chassis_cmc_integrated", func(args ...interface{}) (interface{}, error) {
FQDD, ok := args[0].(string)
if !ok {
return nil, errors.New("Need a string fqdd for addec_system_modular(), but didnt get one")
}
// have to do this in a goroutine because awesome mapper is locked while it processes events
instantiateSvc.Instantiate("chassis_cmc_integrated", map[string]interface{}{"FQDD": FQDD})

return true, nil
})

MakeMaker(l, "ec_system_modular", func(args ...interface{}) (interface{}, error) {
FQDD, ok := args[0].(string)
if !ok {
return nil, errors.New("Need a string fqdd for addec_system_modular(), but didnt get one")
}
// have to do this in a goroutine because awesome mapper is locked while it processes events
instantiateSvc.Instantiate("sled", map[string]interface{}{"FQDD": FQDD})

return true, nil
})

MakeMaker(l, "iom", func(args ...interface{}) (interface{}, error) {
FQDD, ok := args[0].(string)
if !ok {
return nil, errors.New("Need a string fqdd for addiom(), but didnt get one")
}
// have to do this in a goroutine because awesome mapper is locked while it processes events
instantiateSvc.Instantiate("iom", map[string]interface{}{"FQDD": FQDD})

return true, nil
})
// reduce duplicate code by creating a mapping function from a table for the few that are identical
makeMappings := []struct {
name string
instantiate string
}{
{"chassis_cmc_integrated", "chassis_cmc_integrated"},
{"ec_system_modular", "sled"},
{"iom", "iom"},
}

for _, s := range makeMappings {
MakeMaker(l, s.name, func(args ...interface{}) (interface{}, error) {
FQDD, ok := args[0].(string)
if !ok {
return nil, errors.New("Need a string fqdd for addec_system_modular(), but didnt get one")
}
// have to do this in a goroutine because awesome mapper is locked while it processes events
instantiateSvc.Instantiate(s.instantiate, map[string]interface{}{"FQDD": FQDD})

return true, nil
})
}

MakeMaker(l, "ecfan", func(args ...interface{}) (interface{}, error) {
ParentFQDD, ok := args[1].(string)
Expand Down
5 changes: 2 additions & 3 deletions src/dell-resources/attributes/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package attributes
import (
"context"
"errors"
"fmt"
"sync"

"github.com/spf13/viper"
Expand Down Expand Up @@ -43,7 +42,7 @@ func FormatAttributeDump(
return nil
}

fmt.Println(auth)
//fmt.Println(auth)

var ad AttributeData
res := map[string]interface{}{}
Expand All @@ -53,7 +52,7 @@ func FormatAttributeDump(
if ad.ReadAllowed(value, auth) {
res[group+"."+index+"."+name] = ad.Value
} else {
fmt.Println("skipping ", group+"."+index+"."+name)
//fmt.Println("skipping ", group+"."+index+"."+name)
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/redfishresource/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ type RedfishResourceAggregate struct {
ResourceURI string
Plugin string

Properties RedfishResourceProperty
ResultsCache interface{}
ResultsCacheMu sync.RWMutex
CacheTimeSec int
Properties RedfishResourceProperty
ResultsCache interface{}
ResultsCacheAuth *RedfishAuthorizationProperty
ResultsCacheMu sync.RWMutex
CacheTimeSec int

// TODO: need accessor functions for all of these just like property stuff
// above so that everything can be properly locked
Expand Down
39 changes: 0 additions & 39 deletions src/redfishresource/deepcopy.go

This file was deleted.

117 changes: 68 additions & 49 deletions src/redfishresource/http_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package domain

import (
"context"
"errors"
"fmt"
"time"

Expand All @@ -16,13 +17,18 @@ const (
// Static type checking for commands to prevent runtime errors due to typos
var _ = eh.Command(&GET{})

type CompletionEvent struct {
event eh.Event
complete func()
}

// HTTP GET Command
type GET struct {
ID eh.UUID `json:"id"`
CmdID eh.UUID `json:"cmdid"`
HTTPEventBus eh.EventBus
auth *RedfishAuthorizationProperty
outChan chan<- eh.Event
outChan chan<- CompletionEvent
}

func (c *GET) AggregateType() eh.AggregateType { return AggregateType }
Expand All @@ -31,7 +37,7 @@ func (c *GET) CommandType() eh.CommandType { return GETCommand }
func (c *GET) SetAggID(id eh.UUID) { c.ID = id }
func (c *GET) SetCmdID(id eh.UUID) { c.CmdID = id }

func (c *GET) UseEventChan(out chan<- eh.Event) {
func (c *GET) UseEventChan(out chan<- CompletionEvent) {
c.outChan = out
}

Expand All @@ -44,58 +50,71 @@ func (c *GET) Handle(ctx context.Context, a *RedfishResourceAggregate) error {
data := &HTTPCmdProcessedData{
CommandID: c.CmdID,
StatusCode: 200,
Headers: map[string]string{},
}
// TODO: Should be able to discern supported methods from the meta and return those
// TODO: set error status code based on err from ProcessGET
data.Headers = a.Headers

a.ResultsCacheMu.RLock()
if a.ResultsCache != nil {
fmt.Printf(".")
data.Results = a.ResultsCache
a.ResultsCacheMu.RUnlock()
if c.outChan != nil {
c.outChan <- eh.NewEvent(HTTPCmdProcessed, data, time.Now())
} else {
c.HTTPEventBus.PublishEvent(ctx, eh.NewEvent(HTTPCmdProcessed, data, time.Now()))
}
return nil
for k, v := range a.Headers {
data.Headers[k] = v
}
a.ResultsCacheMu.RUnlock()

a.ResultsCacheMu.Lock()
if a.ResultsCache == nil {
fmt.Printf("X")
data.Results, _ = ProcessGET(ctx, &a.Properties, c.auth)
a.ResultsCache = data.Results

// TODO: cache until an invalidation message comes in
// TODO: release cache if not used for a while
// TODO: heartbeat cache to indicate use

// simplest possible solution for now
go func(cacheTime int) {
if cacheTime == 0 {
cacheTime = DefaultCacheTime
}
select {
case <-time.After(time.Duration(cacheTime) * time.Second):
fmt.Printf("E")
a.ResultsCacheMu.Lock()
a.ResultsCache = nil
a.ResultsCacheMu.Unlock()

var complete func()
complete = func() { a.ResultsCacheMu.RUnlock() }

// provide a construct to break out of
for {
// assume cache HIT
a.ResultsCacheMu.RLock()
if a.ResultsCache != nil {
// TODO: we can compare auth/query and return flattend results
// TODO: if auth/query doesn't match, we could use results cache to speed up return by re-flattening
// TODO: if results cache already pre-queried, re-run query

fmt.Printf(".")
data.Results = a.ResultsCache
if c.outChan != nil {
c.outChan <- CompletionEvent{event: eh.NewEvent(HTTPCmdProcessed, data, time.Now()), complete: complete}
}
}(a.CacheTimeSec)
} else {
fmt.Printf("O")
data.Results = a.ResultsCache
}
a.ResultsCacheMu.Unlock()
return nil
}
a.ResultsCacheMu.RUnlock()

// fill in data for cache miss, and then go to the top of the loop
a.ResultsCacheMu.Lock()
if a.ResultsCache != nil {
// redo the comparo from above because we may be here because
// 1) some other thread already updated results cache for us
// 2) we couldn't re-use the results cache because something doesnt match up
}

// if we got here, we need to refresh the data
if a.ResultsCache == nil {
fmt.Printf("X")
NewGet(ctx, &a.Properties, c.auth)

// TODO: flatten results
a.ResultsCache = Flatten(a.Properties.Value)
a.ResultsCacheAuth = c.auth

if c.outChan != nil {
c.outChan <- eh.NewEvent(HTTPCmdProcessed, data, time.Now())
} else {
c.HTTPEventBus.PublishEvent(ctx, eh.NewEvent(HTTPCmdProcessed, data, time.Now()))
// simplest possible solution for now
go func(cacheTime int) {
if cacheTime == 0 {
cacheTime = DefaultCacheTime
}
select {
case <-time.After(time.Duration(cacheTime) * time.Second):
fmt.Printf("E")
a.ResultsCacheMu.Lock()

// TODO: release ephemerals too

a.ResultsCache = nil
a.ResultsCacheMu.Unlock()
}
}(a.CacheTimeSec)
}
a.ResultsCacheMu.Unlock()
}
return nil

return errors.New("Can't happen why did we get here?")
}
Loading

0 comments on commit 147c130

Please sign in to comment.