mirror of
https://github.com/rancher/norman.git
synced 2025-07-15 08:01:53 +00:00
Cleanup channels
This commit is contained in:
parent
67264fa498
commit
6f8ed342d9
@ -33,26 +33,7 @@ func Handler(apiContext *types.APIContext) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func handler(apiContext *types.APIContext) error {
|
func getMatchingSchemas(apiContext *types.APIContext) []*types.Schema {
|
||||||
c, err := upgrader.Upgrade(apiContext.Response, apiContext.Request, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
cancelCtx, cancel := context.WithCancel(apiContext.Request.Context())
|
|
||||||
apiContext.Request = apiContext.Request.WithContext(cancelCtx)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
if _, _, err := c.NextReader(); err != nil {
|
|
||||||
cancel()
|
|
||||||
c.Close()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
apiVersions := apiContext.Request.URL.Query()["apiVersions"]
|
apiVersions := apiContext.Request.URL.Query()["apiVersions"]
|
||||||
resourceTypes := apiContext.Request.URL.Query()["resourceTypes"]
|
resourceTypes := apiContext.Request.URL.Query()["resourceTypes"]
|
||||||
|
|
||||||
@ -69,11 +50,35 @@ func handler(apiContext *types.APIContext) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return schemas
|
||||||
|
}
|
||||||
|
|
||||||
|
func handler(apiContext *types.APIContext) error {
|
||||||
|
schemas := getMatchingSchemas(apiContext)
|
||||||
if len(schemas) == 0 {
|
if len(schemas) == 0 {
|
||||||
return httperror.NewAPIError(httperror.NotFound, "no resources types matched")
|
return httperror.NewAPIError(httperror.NotFound, "no resources types matched")
|
||||||
}
|
}
|
||||||
|
|
||||||
readerGroup, ctx := errgroup.WithContext(apiContext.Request.Context())
|
c, err := upgrader.Upgrade(apiContext.Response, apiContext.Request, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
cancelCtx, cancel := context.WithCancel(apiContext.Request.Context())
|
||||||
|
readerGroup, ctx := errgroup.WithContext(cancelCtx)
|
||||||
|
apiContext.Request = apiContext.Request.WithContext(ctx)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
if _, _, err := c.NextReader(); err != nil {
|
||||||
|
cancel()
|
||||||
|
c.Close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
events := make(chan map[string]interface{})
|
events := make(chan map[string]interface{})
|
||||||
for _, schema := range schemas {
|
for _, schema := range schemas {
|
||||||
streamStore(ctx, readerGroup, apiContext, schema, events)
|
streamStore(ctx, readerGroup, apiContext, schema, events)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package transform
|
package transform
|
||||||
|
|
||||||
import "github.com/rancher/norman/types"
|
import (
|
||||||
|
"github.com/rancher/norman/types"
|
||||||
|
"github.com/rancher/norman/types/convert"
|
||||||
|
)
|
||||||
|
|
||||||
type TransformerFunc func(apiContext *types.APIContext, data map[string]interface{}) (map[string]interface{}, error)
|
type TransformerFunc func(apiContext *types.APIContext, data map[string]interface{}) (map[string]interface{}, error)
|
||||||
|
|
||||||
@ -36,18 +39,13 @@ func (t *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *t
|
|||||||
return t.StreamTransformer(apiContext, c)
|
return t.StreamTransformer(apiContext, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make(chan map[string]interface{})
|
return convert.Chan(c, func(data map[string]interface{}) map[string]interface{} {
|
||||||
go func() {
|
item, err := t.Transformer(apiContext, data)
|
||||||
for item := range c {
|
if err != nil {
|
||||||
item, err := t.Transformer(apiContext, item)
|
return nil
|
||||||
if err == nil && item != nil {
|
|
||||||
result <- item
|
|
||||||
}
|
}
|
||||||
}
|
return item
|
||||||
close(result)
|
}), nil
|
||||||
}()
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
|
func (t *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
|
||||||
|
@ -3,6 +3,7 @@ package wrapper
|
|||||||
import (
|
import (
|
||||||
"github.com/rancher/norman/httperror"
|
"github.com/rancher/norman/httperror"
|
||||||
"github.com/rancher/norman/types"
|
"github.com/rancher/norman/types"
|
||||||
|
"github.com/rancher/norman/types/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Wrap(store types.Store) types.Store {
|
func Wrap(store types.Store) types.Store {
|
||||||
@ -42,20 +43,11 @@ func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make(chan map[string]interface{})
|
return convert.Chan(c, func(data map[string]interface{}) map[string]interface{} {
|
||||||
go func() {
|
return apiContext.FilterObject(&types.QueryOptions{
|
||||||
for item := range c {
|
|
||||||
item = apiContext.FilterObject(&types.QueryOptions{
|
|
||||||
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
|
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
|
||||||
}, item)
|
}, data)
|
||||||
if item != nil {
|
}), nil
|
||||||
result <- item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(result)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StoreWrapper) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
|
func (s *StoreWrapper) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
@ -10,6 +10,20 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Chan(c <-chan map[string]interface{}, f func(map[string]interface{}) map[string]interface{}) chan map[string]interface{} {
|
||||||
|
result := make(chan map[string]interface{})
|
||||||
|
go func() {
|
||||||
|
for data := range c {
|
||||||
|
modified := f(data)
|
||||||
|
if modified != nil {
|
||||||
|
result <- modified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(result)
|
||||||
|
}()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func Singular(value interface{}) interface{} {
|
func Singular(value interface{}) interface{} {
|
||||||
if slice, ok := value.([]string); ok {
|
if slice, ok := value.([]string); ok {
|
||||||
if len(slice) == 0 {
|
if len(slice) == 0 {
|
||||||
|
Loading…
Reference in New Issue
Block a user