Skip to main content
Glama
url_tree.go3.6 kB
package common import ( sharedDiscovery "lunar/shared-model/discovery" "lunar/toolkit-core/configuration" "lunar/toolkit-core/urltree" "os" "time" "github.com/rs/zerolog/log" ) const ( policiesConfigEnvVar = "LUNAR_PROXY_POLICIES_CONFIG" flowsPathParamConfigEnvVar = "LUNAR_FLOWS_PATH_PARAM_CONFIG" idleWaitForFileCreation = 200 * time.Millisecond fileCreationTryAttempts = 100 ) type ( EmptyStruct = struct{} SimpleURLTree = urltree.URLTree[EmptyStruct] SimpleURLTreeI = urltree.URLTreeI[EmptyStruct] ) func NormalizeTree( tree SimpleURLTreeI, urls []string, ) (bool, error) { // Requests URLs are inserted into the tree in order to effectively // normalize it by using this tree's assumed path params feature which // is turned on on this instance upon initialization. // If convergence has occurred, this will be signaled by the return value. convergenceOccurred := false for _, url := range urls { update, err := tree.InsertWithConvergenceIndication(url, &EmptyStruct{}) if err != nil { log.Error(). Err(err). Msgf("Error updating tree with URL: %v", url) return false, err } if !convergenceOccurred && update { convergenceOccurred = update } } return convergenceOccurred, nil } func BuildTree( endpoints sharedDiscovery.KnownEndpoints, maxSplitThreshold int, ) (*SimpleURLTree, error) { tree := urltree.NewURLTree[EmptyStruct](true, maxSplitThreshold) emptyStruct := EmptyStruct{} for _, endpoint := range endpoints.Endpoints { log.Trace().Msgf("BuildTree: Inserting %v into initial tree", endpoint.URL) err := tree.InsertDeclaredURL(endpoint.URL, &emptyStruct) if err != nil { return nil, err } } return tree, nil } func GetPoliciesPath() (string, error) { pathParamConfig := flowsPathParamConfigEnvVar if !IsFlowsEnabled() { pathParamConfig = policiesConfigEnvVar } path, pathErr := configuration.GetPathFromEnvVarOrDefault( pathParamConfig, "./policies.yaml", ) if pathErr != nil { return "", pathErr } return path, nil } func ReadKnownEndpoints() (*sharedDiscovery.KnownEndpoints, error) { path, pathErr := GetPoliciesPath() if pathErr != nil { return nil, pathErr } log.Debug().Msgf("Reading known endpoints from %s", path) waitForFileCreation(path) config, readErr := configuration.DecodeYAML[sharedDiscovery.KnownEndpoints](path) if readErr != nil { return nil, readErr } log.Debug().Msg("Loaded endpoints tree") return config.UnmarshaledData, nil } func GetPoliciesLastModifiedTime() (time.Time, error) { path, pathErr := GetPoliciesPath() if pathErr != nil { return time.Time{}, pathErr } waitForFileCreation(path) info, err := os.Stat(path) if err != nil { log.Debug(). Err(err). Msgf("Failed to get last modified time for %s", path) // If failed to get last modified time, set to the beginning of time return time.Time{}, nil } return info.ModTime(), nil } // This function waits for the file to be created. func waitForFileCreation(path string) { var err error _, err = os.Stat(path) if err == nil { return } ticker := time.NewTicker(idleWaitForFileCreation) for i := 0; i < fileCreationTryAttempts; i++ { <-ticker.C _, err = os.Stat(path) if err == nil { log.Trace().Msgf("File %s was found after %d read attempts", path, i) return } } // After waiting for idleWaitForFileCreation * fileCreationTryAttempts, // if the file is not created, give up and log a message. log.Debug().Msgf("File %s was not created", path) } func IsFlowsEnabled() bool { return os.Getenv("LUNAR_STREAMS_ENABLED") == "true" }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TheLunarCompany/lunar'

If you have feedback or need assistance with the MCP directory API, please join our Discord server