Added admin module
This commit is contained in:
parent
68ccdfd408
commit
76b2395d70
219
admin/admin.go
Normal file
219
admin/admin.go
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
/* Borrowed from: github.com/draxil/gearman_admin */
|
||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Connection to a gearman server
|
||||||
|
type Connection struct {
|
||||||
|
net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
var colrx *regexp.Regexp
|
||||||
|
|
||||||
|
func init(){
|
||||||
|
colrx = regexp.MustCompile("[ \t]+")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to a gearman server
|
||||||
|
// gearadmin, err := gearman_admin.Connect("tcp", "gearman:4730")
|
||||||
|
func Connect(network, address string) (connection *Connection, err error) {
|
||||||
|
connection = &Connection{}
|
||||||
|
connection.Conn, err = net.Dial(network, address)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Error connecting to gearman server: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query connected workers list
|
||||||
|
func (c *Connection) Workers() (workers []Worker, err error) {
|
||||||
|
_, err = c.Write([]byte("workers\n"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
lines, err = read_response(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
workers, err = workers_from_lines(lines)
|
||||||
|
|
||||||
|
return workers, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query known tasks and their statuses
|
||||||
|
func (c *Connection) Status() (statuses []FunctionStatus, err error) {
|
||||||
|
_, err = c.Write([]byte("status\n"))
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Error requesting function status list: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
lines, err = read_response(c)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Error getting function status list: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses, err = func_statuses_from_lines(lines)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Error getting function status list: %s", err.Error())
|
||||||
|
statuses = []FunctionStatus{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func process_line( line string ) []string{
|
||||||
|
parts := colrx.Split(line, -1)
|
||||||
|
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
|
func func_statuses_from_lines(lines []string) (funcs []FunctionStatus, err error){
|
||||||
|
funcs = make([]FunctionStatus, 0, len(lines))
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
parts := process_line(line)
|
||||||
|
|
||||||
|
if len(parts) < 3 {
|
||||||
|
err = ProtocolError("Incomplete status entry only " + strconv.Itoa(len(parts)) + " fields found: " + line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fs FunctionStatus
|
||||||
|
|
||||||
|
fs.Name = parts[0]
|
||||||
|
|
||||||
|
var unfinished, running, workers int
|
||||||
|
|
||||||
|
unfinished, err = strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
err = ProtocolError("bad unfinished count format: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
running, err = strconv.Atoi(parts[2])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = ProtocolError("bad running count format: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
workers, err = strconv.Atoi(parts[3])
|
||||||
|
if err != nil {
|
||||||
|
err = ProtocolError("bad worker count format: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.UnfinishedJobs = unfinished
|
||||||
|
fs.RunningJobs = running
|
||||||
|
fs.Workers = workers
|
||||||
|
|
||||||
|
funcs = append(funcs, fs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func workers_from_lines(lines []string) (workers []Worker, err error) {
|
||||||
|
workers = make([]Worker, 0, len(lines))
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
parts := process_line(line)
|
||||||
|
|
||||||
|
if len(parts) < 4 {
|
||||||
|
err = ProtocolError("Incomplete worker entry")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if parts[3] != `:` {
|
||||||
|
err = ProtocolError("Malformed worker entry '" + parts[3] + "'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
worker := Worker {
|
||||||
|
Fd : parts[0],
|
||||||
|
Addr : parts[1],
|
||||||
|
ClientId : parts[2],
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(parts) > 4 {
|
||||||
|
worker.Functions = parts[4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
workers = append(workers, worker)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Decoded description of a gearman worker
|
||||||
|
type Worker struct {
|
||||||
|
Fd string // File descriptor
|
||||||
|
Addr string // IP address
|
||||||
|
ClientId string // Client ID
|
||||||
|
Functions []string // List of functions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check a worker for a particular function
|
||||||
|
func (w *Worker) HasFunction(funcname string) bool {
|
||||||
|
for _, v := range w.Functions {
|
||||||
|
if v == funcname {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func read_response(r io.Reader) (lines []string, err error) {
|
||||||
|
rdr := bufio.NewReader(r)
|
||||||
|
lines = make([]string, 0, 0)
|
||||||
|
for {
|
||||||
|
line := ""
|
||||||
|
if line, err = rdr.ReadString('\n'); err != nil {
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
} else if line == ".\n" {
|
||||||
|
return lines, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
lines = append(lines, strings.TrimRight(line, "\n"))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decoded description of a functions current status
|
||||||
|
type FunctionStatus struct {
|
||||||
|
Name string // Function name
|
||||||
|
UnfinishedJobs int // Number of unfinished jobs
|
||||||
|
RunningJobs int // Number of running jobs
|
||||||
|
Workers int // Number of workers available
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protocol error
|
||||||
|
type ProtocolError string
|
||||||
|
|
||||||
|
func (p ProtocolError) Error() string {
|
||||||
|
return "ProtoFail: " + string(p)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user