From 1df4312b2fa9961847ddb3668f32070b3d3ad8a3 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 4 Aug 2026 00:19:28 -0700 Subject: [PATCH 1/2] Performance improvement based on pprofile Signed-off-by: Arrobo, Gabriel --- producer/ampolicy.go | 5 ++++- producer/smpolicy.go | 7 +++++-- util/pcf_util.go | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/producer/ampolicy.go b/producer/ampolicy.go index 4210e4b..92ae025 100644 --- a/producer/ampolicy.go +++ b/producer/ampolicy.go @@ -179,7 +179,7 @@ func UpdatePostPoliciesPolAssoIdProcedure(polAssoId string, // HandlePostPolicies Create AM Policy func HandlePostPolicies(request *httpwrapper.Request) *httpwrapper.Response { - logger.AMpolicylog.Infoln("handle AM Policy Create Request") + logger.AMpolicylog.Debugln("handle AM Policy Create Request") polAssoId := request.Params["polAssoId"] policyAssociationRequest := request.Body.(models.PolicyAssociationRequest) @@ -323,5 +323,8 @@ func PostPoliciesProcedure(polAssoId string, // returns UDR Uri of Ue, if ue.UdrUri dose not exist, query NRF to get supported Udr Uri func getUdrUri(ue *pcfContext.UeContext) string { + if ue.UdrUri != "" { + return ue.UdrUri + } return consumer.SendNFInstancesUDR(pcfContext.PCF_Self().NrfUri, ue.Supi) } diff --git a/producer/smpolicy.go b/producer/smpolicy.go index d381341..41ca302 100644 --- a/producer/smpolicy.go +++ b/producer/smpolicy.go @@ -31,7 +31,7 @@ var getSlicePccPolicy = polling.GetSlicePccPolicy // SmPoliciesPost - func HandleCreateSmPolicyRequest(request *httpwrapper.Request) *httpwrapper.Response { - logger.SMpolicylog.Infoln("handle CreateSmPolicy") + logger.SMpolicylog.Debugln("handle CreateSmPolicy") requestDataType := request.Body.(models.SmPolicyContextData) header, response, problemDetails := createSMPolicyProcedure(requestDataType) if response != nil { @@ -77,6 +77,9 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( logger.SMpolicylog.Warnf("can not find corresponding UDR with UE[%s]", ue.Supi) return nil, nil, problemDetail } + if ue.UdrUri == "" { + ue.UdrUri = udrUri + } var smData *models.SmPolicyData smPolicyID := fmt.Sprintf("%s-%d", ue.Supi, request.PduSessionId) smPolicyData := ue.SmPolicyData[smPolicyID] @@ -223,7 +226,7 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( "Location": {locationHeader}, } logger.SMpolicylog.Debugf("SMPolicy PduSessionId[%d] Create", request.PduSessionId) - logger.SMpolicylog.Infof("SM Policy Decision Sent to SMF: %v", decision) + logger.SMpolicylog.Debugf("SM Policy Decision Sent to SMF: %v", decision) return header, decision, nil } diff --git a/util/pcf_util.go b/util/pcf_util.go index 10bb227..9b92083 100644 --- a/util/pcf_util.go +++ b/util/pcf_util.go @@ -15,6 +15,7 @@ import ( "slices" "sort" "strings" + "sync" "github.com/omec-project/openapi/v2/Nudr_DR" "github.com/omec-project/openapi/v2/models" @@ -53,15 +54,27 @@ var ( } ) +var ( + nudrClientMu sync.Mutex + cachedNudrClient *Nudr_DR.APIClient + cachedNudrUri string +) + func GetNudrClient(uri string) *Nudr_DR.APIClient { + nudrClientMu.Lock() + defer nudrClientMu.Unlock() + if cachedNudrClient != nil && cachedNudrUri == uri { + return cachedNudrClient + } configuration := Nudr_DR.NewConfiguration() serverConfig := &configuration.Servers[0] if apiRootVar, exists := serverConfig.Variables["apiRoot"]; exists { apiRootVar.DefaultValue = uri serverConfig.Variables["apiRoot"] = apiRootVar } - client := Nudr_DR.NewAPIClient(configuration) - return client + cachedNudrClient = Nudr_DR.NewAPIClient(configuration) + cachedNudrUri = uri + return cachedNudrClient } // Return ProblemDetail; errString represents Detail and cause represents Cause. From f6da9f05db561e315d68ee7c1bdc752d52f97f78 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 4 Aug 2026 00:55:42 -0700 Subject: [PATCH 2/2] Copilot's comments Signed-off-by: Arrobo, Gabriel --- context/ue.go | 4 +++- producer/ampolicy.go | 20 +++++++++++++++----- producer/smpolicy.go | 3 --- util/pcf_util.go | 11 ++++++++++- util/pcf_util_test.go | 26 ++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/context/ue.go b/context/ue.go index 9002e93..63cec58 100644 --- a/context/ue.go +++ b/context/ue.go @@ -11,6 +11,7 @@ import ( "reflect" "strconv" "strings" + "sync" "github.com/omec-project/openapi/v2/models" "github.com/omec-project/pcf/logger" @@ -20,7 +21,8 @@ import ( // key is supi type UeContext struct { // Udr Ref - UdrUri string + UdrUri string + UdrUriMu sync.RWMutex // SMPolicy SmPolicyData map[string]*UeSmPolicyData // use smPolicyId(ue.Supi-pduSessionId) as key // App Session Related diff --git a/producer/ampolicy.go b/producer/ampolicy.go index 92ae025..14cd8c1 100644 --- a/producer/ampolicy.go +++ b/producer/ampolicy.go @@ -224,7 +224,6 @@ func PostPoliciesProcedure(polAssoId string, logger.AMpolicylog.Errorf("Ue[%s] is not supported in PCF", ue.Supi) return nil, "", problemDetail } - ue.UdrUri = udrUri var reqCopy models.PolicyAssociationRequest if err := util.DeepCopyViaJSON(policyAssociationRequest, &reqCopy); err != nil { @@ -321,10 +320,21 @@ func PostPoliciesProcedure(polAssoId string, return &response, locationHeader, nil } -// returns UDR Uri of Ue, if ue.UdrUri dose not exist, query NRF to get supported Udr Uri +// returns UDR Uri of Ue, caching it on the UeContext after first discovery func getUdrUri(ue *pcfContext.UeContext) string { - if ue.UdrUri != "" { - return ue.UdrUri + ue.UdrUriMu.RLock() + uri := ue.UdrUri + ue.UdrUriMu.RUnlock() + if uri != "" { + return uri } - return consumer.SendNFInstancesUDR(pcfContext.PCF_Self().NrfUri, ue.Supi) + uri = consumer.SendNFInstancesUDR(pcfContext.PCF_Self().NrfUri, ue.Supi) + if uri != "" { + ue.UdrUriMu.Lock() + if ue.UdrUri == "" { + ue.UdrUri = uri + } + ue.UdrUriMu.Unlock() + } + return uri } diff --git a/producer/smpolicy.go b/producer/smpolicy.go index 41ca302..1fdc745 100644 --- a/producer/smpolicy.go +++ b/producer/smpolicy.go @@ -77,9 +77,6 @@ func createSMPolicyProcedure(request models.SmPolicyContextData) ( logger.SMpolicylog.Warnf("can not find corresponding UDR with UE[%s]", ue.Supi) return nil, nil, problemDetail } - if ue.UdrUri == "" { - ue.UdrUri = udrUri - } var smData *models.SmPolicyData smPolicyID := fmt.Sprintf("%s-%d", ue.Supi, request.PduSessionId) smPolicyData := ue.SmPolicyData[smPolicyID] diff --git a/util/pcf_util.go b/util/pcf_util.go index 9b92083..780d646 100644 --- a/util/pcf_util.go +++ b/util/pcf_util.go @@ -55,14 +55,23 @@ var ( ) var ( - nudrClientMu sync.Mutex + nudrClientMu sync.RWMutex cachedNudrClient *Nudr_DR.APIClient cachedNudrUri string ) func GetNudrClient(uri string) *Nudr_DR.APIClient { + nudrClientMu.RLock() + if cachedNudrClient != nil && cachedNudrUri == uri { + client := cachedNudrClient + nudrClientMu.RUnlock() + return client + } + nudrClientMu.RUnlock() + nudrClientMu.Lock() defer nudrClientMu.Unlock() + // double-checked: another goroutine may have updated the cache between the RUnlock and Lock if cachedNudrClient != nil && cachedNudrUri == uri { return cachedNudrClient } diff --git a/util/pcf_util_test.go b/util/pcf_util_test.go index 9df616f..ab917fb 100644 --- a/util/pcf_util_test.go +++ b/util/pcf_util_test.go @@ -73,3 +73,29 @@ func TestDeepCopyViaJSONPreservesNullableField(t *testing.T) { t.Errorf("Arp.PriorityLevel (NullableInt32) lost in copy: got %v, want 5", v) } } + +func resetNudrClientCache() { + nudrClientMu.Lock() + defer nudrClientMu.Unlock() + cachedNudrClient = nil + cachedNudrUri = "" +} + +func TestGetNudrClientReturnsSamePointerForSameURI(t *testing.T) { + resetNudrClientCache() + const uri = "https://udr.example:29504" + c1 := GetNudrClient(uri) + c2 := GetNudrClient(uri) + if c1 != c2 { + t.Error("expected the same *APIClient pointer for repeated calls with the same URI") + } +} + +func TestGetNudrClientReturnsDifferentPointerForDifferentURI(t *testing.T) { + resetNudrClientCache() + c1 := GetNudrClient("https://udr1.example:29504") + c2 := GetNudrClient("https://udr2.example:29504") + if c1 == c2 { + t.Error("expected a different *APIClient pointer when the URI changes") + } +}