func GoServe(addr string) string { gui_.PrepareServer() // find a free port starting from the usual number l, err := net.Listen("tcp", addr) for err != nil { h, p, _ := net.SplitHostPort(addr) addr = fmt.Sprint(h, ":", atoi(p)+1) l, err = net.Listen("tcp", addr) } go func() { LogErr(http.Serve(l, nil)) }() httpfs.Put(OD()+"gui", []byte(l.Addr().String())) return addr }
func (p *Process) Run() { log.Println("=> exec ", p.Path, p.Args) defer p.Out.Close() httpfs.Put(p.OutputURL+"host", []byte(thisAddr)) startTime := AskTime(p.Host()) httpfs.Put(p.OutputURL+"start", []byte(startTime.Format(time.UnixDate))) WLock() // Cmd.Start() modifies state err1 := p.Cmd.Start() // err? WUnlock() if err1 != nil { SetJobError(p.ID, err1) } timeOffset := time.Now().Sub(startTime) // our clock is most likely out-of-sync with host tick := time.NewTicker(KeepaliveInterval) // need initial alive in case watchdog sniffs between start and first alive tick httpfs.Put(p.OutputURL+"alive", []byte(time.Now().Add(timeOffset).Format(time.UnixDate))) go func() { for t := range tick.C { httpfs.Put(p.OutputURL+"alive", []byte(t.Add(timeOffset).Format(time.UnixDate))) } }() err2 := p.Cmd.Wait() if err1 == nil && err2 != nil { SetJobError(p.ID, err2) } tick.Stop() status := -1 // TODO: determine proper status number if err1 != nil || err2 != nil { log.Println(p.Path, p.Args, err1, err2) status = 1 } else { status = 0 } if p.Killed { httpfs.Put(p.OutputURL+"killed", []byte(time.Now().Format(time.UnixDate))) } else { httpfs.Put(p.OutputURL+"exitstatus", []byte(fmt.Sprint(status))) } stopTime := AskTime(p.Host()) nanos := stopTime.Sub(startTime).Nanoseconds() httpfs.Put(p.OutputURL+"duration", []byte(fmt.Sprint(nanos))) if status == 0 { ret, err := RPCCall(p.Host(), "AddFairShare", JobUser(p.ID)+"/"+fmt.Sprint(nanos/1e9)) if err != nil || ret != "" { log.Println("***ERR: AddFairShare", JobUser(p.ID), ret, err) } } return }