Vendor integration dependencies.
This commit is contained in:
parent
dd5e3fba01
commit
55b57c736b
2451 changed files with 731611 additions and 0 deletions
218
integration/vendor/github.com/gambol99/go-marathon/cluster.go
generated
vendored
Normal file
218
integration/vendor/github.com/gambol99/go-marathon/cluster.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
Copyright 2014 Rohith All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package marathon
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
marathonNodeUp = 0
|
||||
marathonNodeDown = 1
|
||||
)
|
||||
|
||||
// Cluster is the interface for the marathon cluster impl
|
||||
type Cluster interface {
|
||||
URL() string
|
||||
// retrieve a member from the cluster
|
||||
GetMember() (string, error)
|
||||
// make the last member as down
|
||||
MarkDown()
|
||||
// the size of the cluster
|
||||
Size() int
|
||||
// the members which are available
|
||||
Active() []string
|
||||
// the members which are NOT available
|
||||
NonActive() []string
|
||||
}
|
||||
|
||||
type marathonCluster struct {
|
||||
sync.RWMutex
|
||||
// the cluster url
|
||||
url string
|
||||
// a link list of members
|
||||
members *marathonNode
|
||||
// the number of members
|
||||
size int
|
||||
// the protocol
|
||||
protocol string
|
||||
// the current host
|
||||
active *marathonNode
|
||||
// the http client
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
// String returns a string representation of the cluster
|
||||
func (r *marathonCluster) String() string {
|
||||
return fmt.Sprintf("url: %s|%s, members: %s, size: %d, active: %s",
|
||||
r.protocol, r.url, r.members, r.size, r.active)
|
||||
}
|
||||
|
||||
type marathonNode struct {
|
||||
// the name / ip address of the host
|
||||
hostname string
|
||||
// the status of the host
|
||||
status int
|
||||
// the next member in the list
|
||||
next *marathonNode
|
||||
}
|
||||
|
||||
func (member marathonNode) String() string {
|
||||
status := "UP"
|
||||
if member.status == marathonNodeDown {
|
||||
status = "DOWN"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("member: %s:%s", member.hostname, status)
|
||||
}
|
||||
|
||||
func newCluster(client *http.Client, marathonURL string) (Cluster, error) {
|
||||
// step: parse the marathon url
|
||||
marathon, err := url.Parse(marathonURL)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidEndpoint
|
||||
}
|
||||
|
||||
// step: check the protocol
|
||||
if marathon.Scheme != "http" && marathon.Scheme != "https" {
|
||||
return nil, ErrInvalidEndpoint
|
||||
}
|
||||
|
||||
cluster := &marathonCluster{
|
||||
client: client,
|
||||
protocol: marathon.Scheme,
|
||||
url: marathonURL,
|
||||
}
|
||||
|
||||
/* step: create a link list of the hosts */
|
||||
var previous *marathonNode
|
||||
for index, host := range strings.SplitN(marathon.Host, ",", -1) {
|
||||
if len(host) == 0 {
|
||||
return nil, ErrInvalidEndpoint
|
||||
}
|
||||
|
||||
// step: create a new cluster member
|
||||
node := new(marathonNode)
|
||||
node.hostname = host
|
||||
cluster.size++
|
||||
// step: if the first member
|
||||
if index == 0 {
|
||||
cluster.members = node
|
||||
cluster.active = node
|
||||
previous = node
|
||||
} else {
|
||||
previous.next = node
|
||||
previous = node
|
||||
}
|
||||
}
|
||||
// step: close the link list
|
||||
previous.next = cluster.active
|
||||
|
||||
return cluster, nil
|
||||
}
|
||||
|
||||
func (r *marathonCluster) URL() string {
|
||||
return r.url
|
||||
}
|
||||
|
||||
func (r *marathonCluster) Active() []string {
|
||||
return r.memberStatus(marathonNodeUp)
|
||||
}
|
||||
|
||||
func (r *marathonCluster) NonActive() []string {
|
||||
return r.memberStatus(marathonNodeDown)
|
||||
}
|
||||
|
||||
func (r *marathonCluster) memberStatus(status int) []string {
|
||||
var list []string
|
||||
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
member := r.members
|
||||
|
||||
for i := 0; i < r.size; i++ {
|
||||
if member.status == status {
|
||||
list = append(list, member.hostname)
|
||||
}
|
||||
member = member.next
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// Retrieve the current member, i.e. the current endpoint in use
|
||||
func (r *marathonCluster) GetMember() (string, error) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
for i := 0; i < r.size; i++ {
|
||||
if r.active.status == marathonNodeUp {
|
||||
return r.GetMarathonURL(r.active), nil
|
||||
}
|
||||
// move to the next member
|
||||
if r.active.next != nil {
|
||||
r.active = r.active.next
|
||||
} else {
|
||||
return "", errors.New("no cluster members available at the moment")
|
||||
}
|
||||
}
|
||||
|
||||
// we reached the end and there were no members available
|
||||
defer r.MarkDown()
|
||||
return "", ErrMarathonDown
|
||||
}
|
||||
|
||||
// Retrieves the current marathon url
|
||||
func (r *marathonCluster) GetMarathonURL(node *marathonNode) string {
|
||||
return fmt.Sprintf("%s://%s", r.protocol, node.hostname)
|
||||
}
|
||||
|
||||
// MarkDown downs node the current endpoint as down and waits for it to come back only
|
||||
func (r *marathonCluster) MarkDown() {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
node := r.active
|
||||
node.status = marathonNodeDown
|
||||
|
||||
// step: create a go-routine to place the member back in
|
||||
go func() {
|
||||
for {
|
||||
response, err := r.client.Get(r.GetMarathonURL(node) + "/ping")
|
||||
if err == nil && response.StatusCode == 200 {
|
||||
node.status = marathonNodeUp
|
||||
return
|
||||
}
|
||||
<-time.After(time.Duration(5 * time.Second))
|
||||
}
|
||||
}()
|
||||
|
||||
// step: move to the next member
|
||||
if r.active.next != nil {
|
||||
r.active = r.active.next
|
||||
}
|
||||
}
|
||||
|
||||
// Six retrieve the size of the cluster
|
||||
func (r *marathonCluster) Size() int {
|
||||
return r.size
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue