-
-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support initializable retriever (#1427)
* Support initializable retriever Signed-off-by: Thomas Poignant <[email protected]> * Update feature_flag_test.go Co-authored-by: Luiz Guilherme Ribeiro <[email protected]> --------- Signed-off-by: Thomas Poignant <[email protected]> Co-authored-by: Luiz Guilherme Ribeiro <[email protected]>
- Loading branch information
1 parent
dc5f5d6
commit fd90988
Showing
6 changed files
with
234 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package retriever | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
|
||
// Manager is a struct that managed the retrievers. | ||
type Manager struct { | ||
ctx context.Context | ||
retrievers []Retriever | ||
onErrorRetriever []Retriever | ||
} | ||
|
||
// NewManager create a new Manager. | ||
func NewManager(ctx context.Context, retrievers []Retriever) *Manager { | ||
return &Manager{ | ||
ctx: ctx, | ||
retrievers: retrievers, | ||
onErrorRetriever: make([]Retriever, 0), | ||
} | ||
} | ||
|
||
// Init the retrievers. | ||
// This function will call the Init function of the retrievers that implements the InitializableRetriever interface. | ||
func (m *Manager) Init(ctx context.Context) error { | ||
return m.initRetrievers(ctx, m.retrievers) | ||
} | ||
|
||
// initRetrievers is a helper function to initialize the retrievers. | ||
func (m *Manager) initRetrievers(ctx context.Context, retrieversToInit []Retriever) error { | ||
m.onErrorRetriever = make([]Retriever, 0) | ||
for _, retriever := range retrieversToInit { | ||
if r, ok := retriever.(InitializableRetriever); ok { | ||
err := r.Init(ctx) | ||
if err != nil { | ||
m.onErrorRetriever = append(m.onErrorRetriever, retriever) | ||
} | ||
} | ||
} | ||
if len(m.onErrorRetriever) > 0 { | ||
return fmt.Errorf("error while initializing the retrievers: %v", m.onErrorRetriever) | ||
} | ||
return nil | ||
} | ||
|
||
// Shutdown the retrievers. | ||
// This function will call the Shutdown function of the retrievers that implements the InitializableRetriever interface. | ||
func (m *Manager) Shutdown(ctx context.Context) error { | ||
onErrorRetriever := make([]Retriever, 0) | ||
for _, retriever := range m.retrievers { | ||
if r, ok := retriever.(InitializableRetriever); ok { | ||
err := r.Shutdown(ctx) | ||
if err != nil { | ||
onErrorRetriever = append(onErrorRetriever, retriever) | ||
} | ||
} | ||
} | ||
if len(onErrorRetriever) > 0 { | ||
return fmt.Errorf("error while shutting down the retrievers: %v", onErrorRetriever) | ||
} | ||
return nil | ||
} | ||
|
||
// GetRetrievers return the retrievers. | ||
// If an error occurred during the initialization of the retrievers, we will return the retrievers that are ready. | ||
func (m *Manager) GetRetrievers() []Retriever { | ||
if len(m.onErrorRetriever) > 0 { | ||
_ = m.initRetrievers(m.ctx, m.onErrorRetriever) | ||
} | ||
return m.retrievers | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package initializableretriever | ||
|
||
import ( | ||
"context" | ||
"github.com/thomaspoignant/go-feature-flag/retriever" | ||
"os" | ||
) | ||
|
||
func NewMockInitializableRetriever(path string, status retriever.Status) Retriever { | ||
return Retriever{ | ||
context: context.Background(), | ||
Path: path, | ||
status: status, | ||
} | ||
} | ||
|
||
// Retriever is a mock provider, that create a file as init step and delete it at shutdown. | ||
type Retriever struct { | ||
context context.Context | ||
Path string | ||
status retriever.Status | ||
} | ||
|
||
// Retrieve is reading the file and return the content | ||
func (r *Retriever) Retrieve(_ context.Context) ([]byte, error) { | ||
content, err := os.ReadFile(r.Path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return content, nil | ||
} | ||
|
||
func (r *Retriever) Init(_ context.Context) error { | ||
yamlString := `flag-xxxx-123: | ||
variations: | ||
A: true | ||
B: false | ||
defaultRule: | ||
variation: A` | ||
|
||
yamlBytes := []byte(yamlString) | ||
return os.WriteFile(r.Path, yamlBytes, 0600) | ||
} | ||
|
||
func (r *Retriever) Shutdown(_ context.Context) error { | ||
return os.Remove(r.Path) | ||
} | ||
|
||
func (r *Retriever) Status() retriever.Status { | ||
return r.status | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters