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