Navigator now supports unweighted and weighted load balancing.
This commit is contained in:
		@ -4,11 +4,14 @@ import (
 | 
				
			|||||||
	"flag"
 | 
						"flag"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/signal"
 | 
						"os/signal"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.starlark.net/starlark"
 | 
						"go.starlark.net/starlark"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -36,6 +39,7 @@ var (
 | 
				
			|||||||
	reloadSignal = make(chan os.Signal)
 | 
						reloadSignal = make(chan os.Signal)
 | 
				
			||||||
	pool         *threadPool
 | 
						pool         *threadPool
 | 
				
			||||||
	counter      uint64
 | 
						counter      uint64
 | 
				
			||||||
 | 
						rnd          = rand.New(rand.NewSource(time.Now().UnixNano()))
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func newThreadPool(size int) *threadPool {
 | 
					func newThreadPool(size int) *threadPool {
 | 
				
			||||||
@ -147,9 +151,56 @@ func GetMapping(ip string) string {
 | 
				
			|||||||
		log.Println("Starlark execute error:", err.Error())
 | 
							log.Println("Starlark execute error:", err.Error())
 | 
				
			||||||
		return ""
 | 
							return ""
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if r, ok := ret.(starlark.String); ok {
 | 
						switch r := ret.(type) {
 | 
				
			||||||
 | 
						case starlark.String:
 | 
				
			||||||
		return string(r)
 | 
							return string(r)
 | 
				
			||||||
 | 
						case *starlark.List:
 | 
				
			||||||
 | 
							val := r.Index(rnd.Intn(r.Len()))
 | 
				
			||||||
 | 
							if s, ok := val.(starlark.String); ok {
 | 
				
			||||||
 | 
								return string(s)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							goto scriptError
 | 
				
			||||||
 | 
						case starlark.Tuple:
 | 
				
			||||||
 | 
							val := r.Index(rnd.Intn(r.Len()))
 | 
				
			||||||
 | 
							if s, ok := val.(starlark.String); ok {
 | 
				
			||||||
 | 
								return string(s)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							goto scriptError
 | 
				
			||||||
 | 
						case *starlark.Dict:
 | 
				
			||||||
 | 
							values := r.Items()
 | 
				
			||||||
 | 
							options := make([]string, r.Len())
 | 
				
			||||||
 | 
							tot := int64(0)
 | 
				
			||||||
 | 
							for i := range values {
 | 
				
			||||||
 | 
								if v, ok := values[i].Index(0).(starlark.String); ok {
 | 
				
			||||||
 | 
									options[i] = string(v)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									goto scriptError
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if v, ok := values[i].Index(1).(starlark.Int); ok {
 | 
				
			||||||
 | 
									if weight, ok := v.Int64(); ok {
 | 
				
			||||||
 | 
										tot += weight
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										goto scriptError
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									goto scriptError
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							sort.Strings(options)
 | 
				
			||||||
 | 
							pos := rnd.Int63n(tot)
 | 
				
			||||||
 | 
							for _, option := range options {
 | 
				
			||||||
 | 
								w, _, _ := r.Get(starlark.String(option))
 | 
				
			||||||
 | 
								v, _ := w.(starlark.Int).Int64()
 | 
				
			||||||
 | 
								pos -= v
 | 
				
			||||||
 | 
								if pos < 0 {
 | 
				
			||||||
 | 
									return option
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Println("Unexpected code execution,",
 | 
				
			||||||
 | 
								"check random logic for *starlark.Dict")
 | 
				
			||||||
 | 
							return options[len(options)-1]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					scriptError:
 | 
				
			||||||
	log.Println("Script returned unexpected result:", ret.String())
 | 
						log.Println("Script returned unexpected result:", ret.String())
 | 
				
			||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,8 +7,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	defaultServer = flag.String("fallback-node",
 | 
						defaultServer = flag.String("fallback-node",
 | 
				
			||||||
		"xe-mci1-us.edge.eve.network",
 | 
							"xe-mci1-us", "Default CDN node in case of any script error")
 | 
				
			||||||
		"Default CDN node in case of any script error")
 | 
					 | 
				
			||||||
	defaultSuffix = flag.String("fallback-suffix",
 | 
						defaultSuffix = flag.String("fallback-suffix",
 | 
				
			||||||
		".edge.eve.network",
 | 
							".edge.eve.network",
 | 
				
			||||||
		"Default CDN suffix in case of any script error")
 | 
							"Default CDN suffix in case of any script error")
 | 
				
			||||||
@ -19,11 +18,15 @@ func Initialize() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Get(ip string) string {
 | 
					func Get(ip string) string {
 | 
				
			||||||
	ret := elf.GetMapping(ip)
 | 
						node := elf.GetMapping(ip)
 | 
				
			||||||
	if ret == "" {
 | 
						if node == "" {
 | 
				
			||||||
		return *defaultServer
 | 
							node = *defaultServer
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret
 | 
						suffix := elf.GetSuffix(ip)
 | 
				
			||||||
 | 
						if suffix == "" {
 | 
				
			||||||
 | 
							suffix = *defaultSuffix
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return node + suffix
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetSuffix(ip string) string {
 | 
					func GetSuffix(ip string) string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
WHOLESALE_INTERNET_10GE = "xe-mci1-us"
 | 
					WHOLESALE_INTERNET_10GE = "xe-mci1-us"
 | 
				
			||||||
HETZNER_FSN_1GE         = "ge-fsn1-de"
 | 
					HETZNER_FSN_1GE         = "ge-fsn1-de"
 | 
				
			||||||
HETZNER_HEL_1GE         = "ge-hel1-fi"
 | 
					HETZNER_HEL_1GE         = "ge-hel1-fi"
 | 
				
			||||||
 | 
					CLOUDCONE_LAX1_1GE		= "ge-lax1-us"
 | 
				
			||||||
 | 
					CLOUDCONE_LAX2_1GE		= "ge-lax2-us"
 | 
				
			||||||
 | 
					CLOUDCONE_LAX_LB		= (CLOUDCONE_LAX1_1GE, CLOUDCONE_LAX2_1GE)
 | 
				
			||||||
default_server          = WHOLESALE_INTERNET_10GE
 | 
					default_server          = WHOLESALE_INTERNET_10GE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CHINA_MAINLAND_SUFFIX = ".eveedge.link"
 | 
					CHINA_MAINLAND_SUFFIX = ".eveedge.link"
 | 
				
			||||||
@ -11,12 +14,20 @@ default_suffix        = GLOBAL_SUFFIX
 | 
				
			|||||||
def getMapping(ip):
 | 
					def getMapping(ip):
 | 
				
			||||||
	info = geoLookup(ip)
 | 
						info = geoLookup(ip)
 | 
				
			||||||
	if not info:
 | 
						if not info:
 | 
				
			||||||
		return default_server + default_suffix
 | 
							return default_server
 | 
				
			||||||
	if info.IspDomain == "ChinaMobile":
 | 
						if info.IspDomain == "ChinaMobile":
 | 
				
			||||||
		return HETZNER_FSN_1GE + CHINA_MAINLAND_SUFFIX
 | 
							return HETZNER_FSN_1GE
 | 
				
			||||||
 | 
						if info.IspDomain == "ChinaTelecom":
 | 
				
			||||||
 | 
							return CLOUDCONE_LAX_LB
 | 
				
			||||||
	if info.CountryCode == "CN":
 | 
						if info.CountryCode == "CN":
 | 
				
			||||||
		return default_server + CHINA_MAINLAND_SUFFIX
 | 
							return default_server
 | 
				
			||||||
	return default_server + GLOBAL_SUFFIX
 | 
						if ip == "0.11.45.14":
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								default_server: 3,
 | 
				
			||||||
 | 
								CLOUDCONE_LAX1_1GE: 2,
 | 
				
			||||||
 | 
								CLOUDCONE_LAX2_1GE: 1,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						return default_server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getNodes():
 | 
					def getNodes():
 | 
				
			||||||
	return ["xe-mci1-us", "ge-fsn1-de", "ge-lax1-us"]
 | 
						return ["xe-mci1-us", "ge-fsn1-de", "ge-lax1-us"]
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user