Skip to content

Commit

Permalink
Fix panic when no master could be parsed
Browse files Browse the repository at this point in the history
Fixes #19
  • Loading branch information
wndhydrnt committed Aug 12, 2015
1 parent f46e6e3 commit 40a2449
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 34 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Improvements:

Bug Fixes:
* [Docs] Syntax error in example configuration file of HAProxy
* [Marathon] Fix ServiceGenerator only picks the first server in the list [#16](https://github.com/wndhydrnt/proxym/issues/16).
* [Marathon] Fix ServiceGenerator only picks the first server in the list [#16](https://github.com/wndhydrnt/proxym/issues/16)
* [Mesos Master] Fix panic when no master could be parsed [#19](https://github.com/wndhydrnt/proxym/issues/19)

## 1.4.0

Expand Down
20 changes: 2 additions & 18 deletions marathon/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import (
"fmt"
"github.com/wndhydrnt/proxym/log"
"github.com/wndhydrnt/proxym/types"
"github.com/wndhydrnt/proxym/utils"
"io/ioutil"
"math/rand"
"net/http"
"strconv"
"strings"
"time"
)

// Generator talks to Marathon and creates a list of services as a result.
Expand All @@ -26,7 +25,7 @@ func (g *Generator) Generate() ([]*types.Service, error) {
var apps Apps
var tasks Tasks

server := pickRandomServer(g.marathonServers)
server := utils.PickRandomFromList(g.marathonServers)

log.AppLog.Debug("Querying Marathon server at '%s'", server)

Expand Down Expand Up @@ -155,18 +154,3 @@ func normalizeId(id string, port int) string {

return "marathon_" + strings.Join(parts, "_") + "_" + strconv.Itoa(port)
}

func pickRandomServer(servers []string) string {
if len(servers) == 1 {
return servers[0]
}

src := rand.NewSource(time.Now().UnixNano())
r := rand.New(src)

max := (len(servers) * 100) - 1

pick := float64(r.Intn(max)) / 100

return servers[int(pick)]
}
22 changes: 14 additions & 8 deletions mesos_master/mesos_master.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package mesos_master
import (
"encoding/json"
"errors"
"fmt"
"github.com/kelseyhightower/envconfig"
"github.com/wndhydrnt/proxym/log"
"github.com/wndhydrnt/proxym/manager"
"github.com/wndhydrnt/proxym/types"
"github.com/wndhydrnt/proxym/utils"
"io/ioutil"
"math/rand"
"net/http"
Expand Down Expand Up @@ -46,7 +48,13 @@ type state struct {
}

func parseLeader(leader string) (types.Host, error) {
address := strings.Split(leader, "@")[1]
pidParts := strings.Split(leader, "@")

if len(pidParts) != 2 {
return types.Host{}, errors.New(fmt.Sprintf("Unable to parse Mesos Master PID %s", leader))
}

address := pidParts[1]

parts := strings.Split(address, ":")

Expand Down Expand Up @@ -90,10 +98,10 @@ func query(hc *http.Client, master string) (string, error) {
return state.Leader, nil
}

func leader(hc *http.Client, masters string) (types.Host, error) {
func leader(hc *http.Client, masters []string) (types.Host, error) {
var host types.Host

master := pickMaster(masters)
master := utils.PickRandomFromList(masters)

leaderId, err := query(hc, master)
if err != nil {
Expand Down Expand Up @@ -131,15 +139,13 @@ func init() {
return
}

hc := &http.Client{}
lr := &leaderRegistry{
mutex: &sync.Mutex{},
}

n := &MesosMasterNotifier{
config: &c,
hc: hc,
leaderRegistry: lr,
n, err := NewMesosNotifier(&c, lr)
if err != nil {
log.ErrorLog.Fatal(err)
}
manager.AddNotifier(n)

Expand Down
18 changes: 16 additions & 2 deletions mesos_master/notifier.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package mesos_master

import (
"errors"
"github.com/wndhydrnt/proxym/log"
"github.com/wndhydrnt/proxym/types"
"net/http"
"strings"
"sync"
"time"
)
Expand All @@ -13,6 +15,7 @@ type MesosMasterNotifier struct {
currentLeader types.Host
hc *http.Client
leaderRegistry *leaderRegistry
masters []string
}

func (m *MesosMasterNotifier) Start(refresh chan string, quit chan int, wg *sync.WaitGroup) {
Expand All @@ -29,9 +32,9 @@ func (m *MesosMasterNotifier) Start(refresh chan string, quit chan int, wg *sync
}

func (m *MesosMasterNotifier) pollLeader(refresh chan string) {
host, err := leader(m.hc, m.config.Masters)
host, err := leader(m.hc, m.masters)
if err != nil {
log.ErrorLog.Error("Error getting current Mesos Master leader: '%s'", err)
log.ErrorLog.Error("Error getting current Mesos Master leader: %s", err)
return
}

Expand All @@ -47,3 +50,14 @@ func (m *MesosMasterNotifier) pollLeader(refresh chan string) {

m.currentLeader = host
}

func NewMesosNotifier(c *Config, lr *leaderRegistry) (*MesosMasterNotifier, error) {
hc := &http.Client{}
masters := strings.Split(c.Masters, ",")

if len(masters) == 0 {
return nil, errors.New("PROXYM_MESOS_MASTER_MASTERS is not set")
}

return &MesosMasterNotifier{config: c, hc: hc, leaderRegistry: lr, masters: masters}, nil
}
9 changes: 4 additions & 5 deletions mesos_master/notifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ func TestShouldTriggerRefreshWhenMasterChanges(t *testing.T) {
mutex: &sync.Mutex{},
}

n := MesosMasterNotifier{
config: &Config{
n, _ := NewMesosNotifier(
&Config{
Masters: ts.URL,
PollInterval: 1,
},
hc: &http.Client{},
leaderRegistry: lr,
}
lr,
)

go n.Start(refresh, make(chan int), wg)

Expand Down
21 changes: 21 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package utils

import (
"math/rand"
"time"
)

func PickRandomFromList(list []string) string {
if len(list) == 1 {
return list[0]
}

src := rand.NewSource(time.Now().UnixNano())
r := rand.New(src)

max := (len(list) * 100) - 1

pick := float64(r.Intn(max)) / 100

return list[int(pick)]
}

0 comments on commit 40a2449

Please sign in to comment.