func (c *Client) ServiceWork(wr io.ReadWriter) { reader := gob.NewDecoder(wr) writer := gob.NewEncoder(wr) defer func() { if c.Work != nil { work := c.clearWork() var err string if e := recover(); e != nil { err = fmt.Sprint(e) } c.Owner.retryWork(work, "ServiceWork loop ended "+err) } }() for { work, err := c.Owner.getWork() if err != nil { log.Println(err) continue } log.Println("got work from job", work.PartOf().Id) c.Work = work work.SetStatus("Sending work to client " + c.ClientInfo.ComputerName) work.Dispatch(c.ClientInfo) comms, err := work.PartOf().CreateWorkComms(work) if err != nil { log.Println("ServiceWork writer.Encode(comms) error", err) c.FrameWorkError(err) return } err = writer.Encode(comms) if err != nil { log.Println("ServiceWork writer.Encode(comms) error", err) c.FrameWorkError(err) return } work.SetStatus("Awaiting response from client " + c.ClientInfo.ComputerName) var res *Hyades.WorkResult = new(Hyades.WorkResult) err = reader.Decode(res) if err != nil { log.Println("ServiceWork reader.Decode(res) error", err) c.FrameWorkError(err) return } res.SetEnv(NopCloser(wr)) c.clearWork() if res != nil && res.Error == "" { c.Owner.doneWork(work, res) c.Owner.Stats.DonePart(c.ClientInfo) } else { c.Owner.retryWork(work, res.Error) log.Println("ServiceWork ErrOutStream", res.ErrOutStream) log.Println("ServiceWork StdOutStream", res.StdOutStream) c.Owner.Log.Println("Client ", c.ClientInfo.ComputerName, "(", c.ClientInfo.OperatingSystem, ") terminated simulation with error:", res.Error) c.Owner.Stats.JobError() } err = c.Owner.db.SaveWork(work) if err != nil { log.Println("Saving work failed", err) } else { log.Println("Saved work", work.PartOf().Name, work.Command, work.Parameters) } } }