From 6ead0d568920af35184ade09dad7a429a86f0d77 Mon Sep 17 00:00:00 2001
From: Chandrajeet Nagar <73836012+chandrajeetn@users.noreply.github.com>
Date: Wed, 14 May 2025 04:34:20 +0530
Subject: [PATCH 1/5] tested and added root org support
---
.gitignore | 6 +++
go.mod | 4 +-
go.sum | 8 ---
localEvaluation/localEvaluation.go | 83 +++++++++++++++++++++---------
model/lums.go | 18 +++++++
pkg/experiment/local/client.go | 7 ++-
pkg/rootOrg/client.go | 59 +++++++++++++++++++++
pkg/rootOrg/config.go | 17 ++++++
pkg/rootOrg/poller.go | 28 ++++++++++
pkg/rootOrg/rootOrg.go | 70 +++++++++++++++++++++++++
10 files changed, 261 insertions(+), 39 deletions(-)
create mode 100644 .gitignore
create mode 100644 model/lums.go
create mode 100644 pkg/rootOrg/client.go
create mode 100644 pkg/rootOrg/config.go
create mode 100644 pkg/rootOrg/poller.go
create mode 100644 pkg/rootOrg/rootOrg.go
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..244038b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+vendor/
+.idea/
+.vscode/
+.DS_Store
+internal/.DS_Store
+local_evaluation.go
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 79eb15c..6513118 100644
--- a/go.mod
+++ b/go.mod
@@ -3,14 +3,14 @@ module github.com/LambdaTest/lambda-featureflag-go-sdk
go 1.20
require (
+ github.com/amplitude/analytics-go v1.0.1
github.com/joho/godotenv v1.5.1
github.com/sirupsen/logrus v1.9.3
+ github.com/spaolacci/murmur3 v1.1.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
require (
- github.com/amplitude/analytics-go v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
- github.com/spaolacci/murmur3 v1.1.0 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
diff --git a/go.sum b/go.sum
index 8bab424..c7c8117 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,5 @@
github.com/amplitude/analytics-go v1.0.1 h1:rrdC5VBctlJigSk0kw7ktwSijob/wyH4bop2SqWduCU=
github.com/amplitude/analytics-go v1.0.1/go.mod h1:kAQG8OQ6aPOxZrEZ3+/NFCfxdYSyjqXZhgkjWFD3/vo=
-github.com/amplitude/experiment-go-server v1.3.0 h1:zsrbMiaI6yDwNesDREX6Wy83w4kZ0vqJEdxko69DmU8=
-github.com/amplitude/experiment-go-server v1.3.0/go.mod h1:5HERnGGohucx2mNr/0fLeQ9xFWNmeMbtzsxH2beB+hs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -16,14 +14,9 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -31,4 +24,3 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/localEvaluation/localEvaluation.go b/localEvaluation/localEvaluation.go
index f2e38a2..4f4120a 100644
--- a/localEvaluation/localEvaluation.go
+++ b/localEvaluation/localEvaluation.go
@@ -2,23 +2,25 @@ package localEvaluation
import (
"fmt"
-
- "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment"
- "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment/local"
- "github.com/joho/godotenv"
-
"os"
"strconv"
"time"
+
+ "github.com/joho/godotenv"
+
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment"
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment/local"
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/rootOrg"
)
var (
client *local.Client
- LocalEvaluationConfigDebug = true
- LocalEvaluationConfigServerUrl = "https://api.lambdatest.com"
- LocalEvaluationConfigPollInterval = 120
- LocalEvaluationConfigPollerRequestTimeout = 60
- LocalEvaluationDeploymentKey = "server-jAqqJaX3l8PgNiJpcv9j20ywPzANQQFh"
+ rootOrgClient *rootOrg.Client
+ localEvaluationConfigDebug = true
+ localEvaluationConfigServerUrl = "https://api.lambdatest.com"
+ localEvaluationConfigPollInterval = 120
+ localEvaluationConfigPollerRequestTimeout = 60
+ localEvaluationDeploymentKey = "server-jAqqJaX3l8PgNiJpcv9j20ywPzANQQFh"
retries = 5
)
@@ -43,7 +45,7 @@ type UserProperties struct {
TemplateId string `json:"template_id,omitempty"`
}
-func Init() {
+func initVars() {
err := godotenv.Load()
if err != nil {
fmt.Printf("No .env file found")
@@ -52,31 +54,31 @@ func Init() {
}
if os.Getenv("LOCAL_EVALUATION_CONFIG_DEBUG") != "" {
- LocalEvaluationConfigDebug, _ = strconv.ParseBool(os.Getenv("LOCAL_EVALUATION_CONFIG_DEBUG"))
+ localEvaluationConfigDebug, _ = strconv.ParseBool(os.Getenv("LOCAL_EVALUATION_CONFIG_DEBUG"))
}
if os.Getenv("LOCAL_EVALUATION_CONFIG_SERVER_URL") != "" {
- LocalEvaluationConfigServerUrl = os.Getenv("LOCAL_EVALUATION_CONFIG_SERVER_URL")
+ localEvaluationConfigServerUrl = os.Getenv("LOCAL_EVALUATION_CONFIG_SERVER_URL")
}
if os.Getenv("LOCAL_EVALUATION_CONFIG_POLL_INTERVAL") != "" {
- LocalEvaluationConfigPollInterval, _ = strconv.Atoi(os.Getenv("LOCAL_EVALUATION_CONFIG_POLL_INTERVAL"))
+ localEvaluationConfigPollInterval, _ = strconv.Atoi(os.Getenv("LOCAL_EVALUATION_CONFIG_POLL_INTERVAL"))
}
if os.Getenv("LOCAL_EVALUATION_CONFIG_POLLER_REQUEST_TIMEOUT") != "" {
- LocalEvaluationConfigPollerRequestTimeout, _ = strconv.Atoi(os.Getenv("LOCAL_EVALUATION_CONFIG_POLLER_REQUEST_TIMEOUT"))
+ localEvaluationConfigPollerRequestTimeout, _ = strconv.Atoi(os.Getenv("LOCAL_EVALUATION_CONFIG_POLLER_REQUEST_TIMEOUT"))
}
if os.Getenv("LOCAL_EVALUATION_DEPLOYMENT_KEY") != "" {
- LocalEvaluationDeploymentKey = os.Getenv("LOCAL_EVALUATION_DEPLOYMENT_KEY")
+ localEvaluationDeploymentKey = os.Getenv("LOCAL_EVALUATION_DEPLOYMENT_KEY")
}
}
func Initialize() {
- Init()
+ initVars()
config := local.Config{
- Debug: LocalEvaluationConfigDebug,
- ServerUrl: LocalEvaluationConfigServerUrl,
- FlagConfigPollerInterval: time.Duration(LocalEvaluationConfigPollInterval) * time.Second,
- FlagConfigPollerRequestTimeout: time.Duration(LocalEvaluationConfigPollerRequestTimeout) * time.Second,
+ Debug: localEvaluationConfigDebug,
+ ServerUrl: localEvaluationConfigServerUrl,
+ FlagConfigPollerInterval: time.Duration(localEvaluationConfigPollInterval) * time.Second,
+ FlagConfigPollerRequestTimeout: time.Duration(localEvaluationConfigPollerRequestTimeout) * time.Second,
}
- client = local.Initialize(LocalEvaluationDeploymentKey, &config)
+ client = local.Initialize(localEvaluationDeploymentKey, &config)
var err error
for i := 0; i < retries; i++ {
err = client.Start()
@@ -111,8 +113,31 @@ func InitializeWithConfig(conf local.Config, deploymentKey string) {
}
}
+func InitializeRootOrg() {
+ initVars()
+ rootOrgClient = rootOrg.NewClient(localEvaluationDeploymentKey, &rootOrg.Config{
+ ServerUrl: localEvaluationConfigServerUrl,
+ FlagConfigPollerInterval: time.Duration(localEvaluationConfigPollInterval) * time.Second,
+ FlagConfigPollerRequestTimeout: time.Duration(localEvaluationConfigPollerRequestTimeout) * time.Second,
+ })
+ var err error
+ for i := 0; i < retries; i++ {
+ err = rootOrgClient.Start()
+ if err != nil {
+ err = fmt.Errorf("unable to get root orgs with given config %+v attempt:%v with error %s", rootOrgClient.Config, i+1, err.Error())
+ continue
+ } else {
+ break
+ }
+ }
+ if err != nil {
+ err = fmt.Errorf("unable to get root orgs with given config %+v with error %s", rootOrgClient.Config, err.Error())
+ panic(err)
+ }
+}
+
func fetch(user UserProperties) (map[string]experiment.Variant, error) {
- userProp := map[string]interface{}{
+ userProp := map[string]any{
"org_id": user.OrgId,
"org_name": user.OrgName,
"username": user.Username,
@@ -128,6 +153,14 @@ func fetch(user UserProperties) (map[string]experiment.Variant, error) {
UserProperties: userProp,
}
+ // Evaluate root org to get the parent org id
+ if expUser.UserProperties["org_id"] != "" && rootOrgClient != nil {
+ rootOrg, ok := rootOrgClient.Evaluate(expUser.UserProperties["org_id"])
+ if ok {
+ expUser.UserProperties["org_id"] = rootOrg
+ }
+ }
+
result, err := client.EvaluateV2(&expUser, []string{})
if err != nil {
return nil, err
@@ -137,7 +170,7 @@ func fetch(user UserProperties) (map[string]experiment.Variant, error) {
func getValue(flagName string, user UserProperties) Variant {
result, _ := fetch(user)
- if result != nil && len(result) != 0 {
+ if len(result) != 0 {
if value, ok := result[flagName]; ok {
return Variant{
Key: value.Key,
@@ -151,7 +184,7 @@ func getValue(flagName string, user UserProperties) Variant {
func getMapOfValue(user UserProperties) map[string]interface{} {
flags := make(map[string]interface{})
result, _ := fetch(user)
- if result != nil && len(result) != 0 {
+ if len(result) != 0 {
for k, v := range result {
if v.Value != "" {
flags[k] = v.Value
diff --git a/model/lums.go b/model/lums.go
new file mode 100644
index 0000000..74728b8
--- /dev/null
+++ b/model/lums.go
@@ -0,0 +1,18 @@
+package model
+
+type OrgId int64
+
+type OrgMap map[OrgId]OrgId
+
+// ErrorResponse represents the error response from the LUMS API
+type ErrorResponse struct {
+ Type string `json:"type"`
+ Title string `json:"title"`
+ Message string `json:"message"`
+}
+
+// SuccessResponse represents the success response from the LUMS API
+type SuccessResponse struct {
+ Type string `json:"type"`
+ Data OrgMap `json:"data"`
+}
diff --git a/pkg/experiment/local/client.go b/pkg/experiment/local/client.go
index e6aabdb..ed0bd16 100644
--- a/pkg/experiment/local/client.go
+++ b/pkg/experiment/local/client.go
@@ -4,18 +4,17 @@ import (
"context"
"encoding/json"
"fmt"
- "github.com/amplitude/analytics-go/amplitude"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"sync"
- "github.com/LambdaTest/lambda-featureflag-go-sdk/internal/evaluation"
-
- "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment"
+ "github.com/amplitude/analytics-go/amplitude"
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/internal/evaluation"
"github.com/LambdaTest/lambda-featureflag-go-sdk/internal/logger"
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/pkg/experiment"
)
var clients = map[string]*Client{}
diff --git a/pkg/rootOrg/client.go b/pkg/rootOrg/client.go
new file mode 100644
index 0000000..2554557
--- /dev/null
+++ b/pkg/rootOrg/client.go
@@ -0,0 +1,59 @@
+package rootOrg
+
+import (
+ "strconv"
+ "sync"
+
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/model"
+)
+
+type Client struct {
+ apiKey string
+ Config *Config
+ poller *poller
+ flags *model.OrgMap
+ flagsMutex *sync.RWMutex
+}
+
+func NewClient(apiKey string, config *Config) *Client {
+ return &Client{
+ apiKey: apiKey,
+ Config: config,
+ flagsMutex: &sync.RWMutex{},
+ flags: &model.OrgMap{},
+ poller: newPoller(),
+ }
+}
+
+func (c *Client) Start() error {
+ c.poller = newPoller()
+ c.poller.Poll(c.Config.FlagConfigPollerInterval, func() {
+ c.pollFlags()
+ })
+ return c.pollFlags()
+}
+
+func (c *Client) Stop() {
+ close(c.poller.shutdown)
+}
+
+func (c *Client) pollFlags() error {
+ c.flagsMutex.Lock()
+ defer c.flagsMutex.Unlock()
+ rootOrgs, err := GetRootOrgs(c.apiKey, c.Config.ServerUrl, c.Config.FlagConfigPollerRequestTimeout)
+ if err != nil {
+ return err
+ }
+ c.flags = rootOrgs
+ return nil
+}
+
+func (c *Client) Evaluate(orgId any) (any, bool) {
+ c.flagsMutex.RLock()
+ defer c.flagsMutex.RUnlock()
+
+ orgIdStr, _ := orgId.(string)
+ orgIdInt, _ := strconv.ParseInt(orgIdStr, 10, 64)
+ org, ok := (*c.flags)[model.OrgId(orgIdInt)]
+ return org, ok
+}
diff --git a/pkg/rootOrg/config.go b/pkg/rootOrg/config.go
new file mode 100644
index 0000000..0f33383
--- /dev/null
+++ b/pkg/rootOrg/config.go
@@ -0,0 +1,17 @@
+package rootOrg
+
+import (
+ "time"
+)
+
+type Config struct {
+ ServerUrl string
+ FlagConfigPollerInterval time.Duration
+ FlagConfigPollerRequestTimeout time.Duration
+}
+
+var DefaultConfig = &Config{
+ ServerUrl: "https://api.lambdatest.com",
+ FlagConfigPollerInterval: 120 * time.Second,
+ FlagConfigPollerRequestTimeout: 60 * time.Second,
+}
diff --git a/pkg/rootOrg/poller.go b/pkg/rootOrg/poller.go
new file mode 100644
index 0000000..48727c0
--- /dev/null
+++ b/pkg/rootOrg/poller.go
@@ -0,0 +1,28 @@
+package rootOrg
+
+import "time"
+
+type poller struct {
+ shutdown chan bool
+}
+
+func newPoller() *poller {
+ return &poller{
+ shutdown: make(chan bool),
+ }
+}
+
+func (p *poller) Poll(interval time.Duration, function func()) {
+ ticker := time.NewTicker(interval)
+ go func() {
+ for {
+ select {
+ case <-p.shutdown:
+ ticker.Stop()
+ return
+ case <-ticker.C:
+ go function()
+ }
+ }
+ }()
+}
diff --git a/pkg/rootOrg/rootOrg.go b/pkg/rootOrg/rootOrg.go
new file mode 100644
index 0000000..6f75819
--- /dev/null
+++ b/pkg/rootOrg/rootOrg.go
@@ -0,0 +1,70 @@
+package rootOrg
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/LambdaTest/lambda-featureflag-go-sdk/model"
+)
+
+// lumsClient handles LUMS API operations
+type lumsClient struct {
+ httpClient *http.Client
+ baseURL string
+ timeout time.Duration
+}
+
+// NewLumsClient creates a new LUMSClient
+func newLumsClient(httpClient *http.Client, url string, timeout time.Duration) *lumsClient {
+ return &lumsClient{
+ httpClient: httpClient,
+ baseURL: url,
+ timeout: timeout,
+ }
+}
+
+func (c *lumsClient) getRootOrgs(apiKey string) (*model.OrgMap, error) {
+ ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
+ defer cancel()
+ url := fmt.Sprintf("%s/sdk/rootOrg", c.baseURL)
+
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create request: %v", err)
+ }
+ req.Header.Set("Authorization", fmt.Sprintf("token %s", apiKey))
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return nil, fmt.Errorf("failed to make request: %v", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ var errResp model.ErrorResponse
+ if err := json.NewDecoder(resp.Body).Decode(&errResp); err != nil {
+ return nil, fmt.Errorf("failed to decode error response: %v", err)
+ }
+ return nil, fmt.Errorf("%s: %s", errResp.Title, errResp.Message)
+ }
+
+ var successResp model.SuccessResponse
+ err = json.NewDecoder(resp.Body).Decode(&successResp)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode success response: %v", err)
+ }
+
+ return &successResp.Data, nil
+}
+
+// GetRootOrgs is a convenience function that uses the default HTTP client
+func GetRootOrgs(apiKey string, url string, timeout time.Duration) (*model.OrgMap, error) {
+ client := newLumsClient(http.DefaultClient, url, timeout)
+ result, err := client.getRootOrgs(apiKey)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
From b2dc0bb7d523b390702222c655639a0f8a5dc170 Mon Sep 17 00:00:00 2001
From: Chandrajeet Nagar <73836012+chandrajeetn@users.noreply.github.com>
Date: Wed, 14 May 2025 04:39:28 +0530
Subject: [PATCH 2/5] copilot feedback
---
pkg/rootOrg/client.go | 10 ++++++++--
pkg/rootOrg/poller.go | 4 ++--
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/pkg/rootOrg/client.go b/pkg/rootOrg/client.go
index 2554557..493a262 100644
--- a/pkg/rootOrg/client.go
+++ b/pkg/rootOrg/client.go
@@ -52,8 +52,14 @@ func (c *Client) Evaluate(orgId any) (any, bool) {
c.flagsMutex.RLock()
defer c.flagsMutex.RUnlock()
- orgIdStr, _ := orgId.(string)
- orgIdInt, _ := strconv.ParseInt(orgIdStr, 10, 64)
+ orgIdStr, ok := orgId.(string)
+ if !ok {
+ return nil, false
+ }
+ orgIdInt, err := strconv.ParseInt(orgIdStr, 10, 64)
+ if err != nil {
+ return nil, false
+ }
org, ok := (*c.flags)[model.OrgId(orgIdInt)]
return org, ok
}
diff --git a/pkg/rootOrg/poller.go b/pkg/rootOrg/poller.go
index 48727c0..0a94863 100644
--- a/pkg/rootOrg/poller.go
+++ b/pkg/rootOrg/poller.go
@@ -3,12 +3,12 @@ package rootOrg
import "time"
type poller struct {
- shutdown chan bool
+ shutdown chan struct{}
}
func newPoller() *poller {
return &poller{
- shutdown: make(chan bool),
+ shutdown: make(chan struct{}),
}
}
From 5f19995544006ab17150ca210141d639db1b4c10 Mon Sep 17 00:00:00 2001
From: Chandrajeet Nagar <73836012+chandrajeetn@users.noreply.github.com>
Date: Wed, 14 May 2025 04:42:35 +0530
Subject: [PATCH 3/5] removed panic
---
localEvaluation/localEvaluation.go | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/localEvaluation/localEvaluation.go b/localEvaluation/localEvaluation.go
index 4f4120a..7e7f124 100644
--- a/localEvaluation/localEvaluation.go
+++ b/localEvaluation/localEvaluation.go
@@ -113,7 +113,7 @@ func InitializeWithConfig(conf local.Config, deploymentKey string) {
}
}
-func InitializeRootOrg() {
+func InitializeRootOrg() error {
initVars()
rootOrgClient = rootOrg.NewClient(localEvaluationDeploymentKey, &rootOrg.Config{
ServerUrl: localEvaluationConfigServerUrl,
@@ -132,8 +132,9 @@ func InitializeRootOrg() {
}
if err != nil {
err = fmt.Errorf("unable to get root orgs with given config %+v with error %s", rootOrgClient.Config, err.Error())
- panic(err)
+ return err
}
+ return nil
}
func fetch(user UserProperties) (map[string]experiment.Variant, error) {
From 4bb4f5b9e61f532e09b639bf39b2d6af6962ff33 Mon Sep 17 00:00:00 2001
From: Chandrajeet Nagar <73836012+chandrajeetn@users.noreply.github.com>
Date: Thu, 15 May 2025 02:49:08 +0530
Subject: [PATCH 4/5] reduced timeout to 10 seconds
---
pkg/rootOrg/config.go | 2 +-
pkg/rootOrg/rootOrg.go | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/pkg/rootOrg/config.go b/pkg/rootOrg/config.go
index 0f33383..0e703d2 100644
--- a/pkg/rootOrg/config.go
+++ b/pkg/rootOrg/config.go
@@ -13,5 +13,5 @@ type Config struct {
var DefaultConfig = &Config{
ServerUrl: "https://api.lambdatest.com",
FlagConfigPollerInterval: 120 * time.Second,
- FlagConfigPollerRequestTimeout: 60 * time.Second,
+ FlagConfigPollerRequestTimeout: 10 * time.Second,
}
diff --git a/pkg/rootOrg/rootOrg.go b/pkg/rootOrg/rootOrg.go
index 6f75819..bb92552 100644
--- a/pkg/rootOrg/rootOrg.go
+++ b/pkg/rootOrg/rootOrg.go
@@ -61,7 +61,11 @@ func (c *lumsClient) getRootOrgs(apiKey string) (*model.OrgMap, error) {
// GetRootOrgs is a convenience function that uses the default HTTP client
func GetRootOrgs(apiKey string, url string, timeout time.Duration) (*model.OrgMap, error) {
- client := newLumsClient(http.DefaultClient, url, timeout)
+ client := newLumsClient(&http.Client{
+ Transport: &http.Transport{
+ DisableKeepAlives: true,
+ },
+ }, url, timeout)
result, err := client.getRootOrgs(apiKey)
if err != nil {
return nil, err
From 3d607e7b7b0e3fc7ad64ab4ac7067e8405274f0e Mon Sep 17 00:00:00 2001
From: Chandrajeet Nagar <73836012+chandrajeetn@users.noreply.github.com>
Date: Thu, 15 May 2025 03:19:22 +0530
Subject: [PATCH 5/5] starting default
---
localEvaluation/localEvaluation.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/localEvaluation/localEvaluation.go b/localEvaluation/localEvaluation.go
index 7e7f124..30514e9 100644
--- a/localEvaluation/localEvaluation.go
+++ b/localEvaluation/localEvaluation.go
@@ -86,6 +86,7 @@ func Initialize() {
err = fmt.Errorf("unable to create local evaluation client with given config %+v attempt:%v with error %s", config, i+1, err.Error())
continue
} else {
+ InitializeRootOrg()
break
}
}
@@ -104,6 +105,7 @@ func InitializeWithConfig(conf local.Config, deploymentKey string) {
err = fmt.Errorf("unable to create local evaluation client with given config %+v attempt:%v with error %s", conf, i+1, err.Error())
continue
} else {
+ InitializeRootOrg()
break
}
}
@@ -114,7 +116,6 @@ func InitializeWithConfig(conf local.Config, deploymentKey string) {
}
func InitializeRootOrg() error {
- initVars()
rootOrgClient = rootOrg.NewClient(localEvaluationDeploymentKey, &rootOrg.Config{
ServerUrl: localEvaluationConfigServerUrl,
FlagConfigPollerInterval: time.Duration(localEvaluationConfigPollInterval) * time.Second,