func TestBigPriority(t *testing.T) { var numQueues uint64 = 1<<64 - 1 q := NewPriority(numQueues, func() (Queue, error) { q := NewSimple(10, 1) return q, nil }) defer q.Stop() q.Process() job := job.NewSimple("name", numQueues-1, func() error { delta, err := rand.Int63n(1000, "go") if err != nil { return e.Forward(err) } delta++ time.Sleep(time.Duration(delta) * time.Millisecond) return nil }) err := q.Add(job) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } job.Returns(&err) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } }
func (vs *VirtualServer) SendToQueue(f interface{}, args ...interface{}) error { rnd, err := rand.Chars(10, rand.NumberLetters, "go") if err != nil { return e.Forward(err) } job := job.NewSimple(vs.VirtualServerName+rnd, vs.Prio, f, args...) vs.status.Log(status.Verbose, "Add job %v for %v to queue %v.", job.Name(), vs.VirtualServerName, vs.Prio) err = vs.Queue.Add(job) if err != nil { return e.Forward(err) } vs.status.Log(status.Verbose, "Waiting job %v return.", job.Name()) job.Returns(&err) if err != nil { return e.Forward(err) } vs.status.Log(status.Verbose, "Job %v returned.", job.Name()) return nil }
func TestSimpleQueue(t *testing.T) { q := NewSimple(10, 1) defer q.Stop() q.Process() j := 0 job := job.NewSimple("test", 0, func() { j++ return }) err := q.Add(job) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } job.Returns() }
func TestPrioritySequence(t *testing.T) { const num = 5 q := NewPriority(num, func() (Queue, error) { q := NewSimple(10, 1) return q, nil }) defer q.Stop() q.Process() datas := make([]time.Time, num) jobs := make([]job.Job, num) for i := 0; i < num; i++ { name := "test_" + strconv.FormatInt(int64(i), 10) job := job.NewSimple(name, uint64(i), func(i int) error { datas[i] = time.Now() delta, err := rand.Int63n(1000, "go") if err != nil { return e.Forward(err) } delta++ time.Sleep(time.Duration(delta) * time.Millisecond) return nil }, i) err := q.Add(job) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } jobs[i] = job } for _, j := range jobs { var err error j.Returns(&err) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } } for i := 0; i < len(datas)-1; i++ { if datas[i].After(datas[i+1]) { t.Fatal("not in sequence") } } }
func TestPriority(t *testing.T) { q := NewPriority(10, func(size int) (Queue, error) { q := NewSimple(size, 2) return q, nil }, 5) defer q.Stop() q.Process() jobs := make([]job.Job, NumJobsPrio) result := make([]string, NumJobsPrio) for i := 0; i < len(jobs); i++ { name := "test_" + strconv.FormatInt(int64(i), 10) prio, err := rand.Int63n(10, "go") if err != nil { t.Fatal(e.Trace(e.Forward(err))) } job := job.NewSimple(name, uint64(prio), func(i int) error { delta, err := rand.Int63n(1000, "go") if err != nil { return e.Forward(err) } delta++ time.Sleep(time.Duration(delta) * time.Millisecond) result[i] = name return nil }, i) jobs[i] = job err = q.Add(job) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } } for i, j := range jobs { var err error j.Returns(&err) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } name := "test_" + strconv.FormatInt(int64(i), 10) if result[i] != name { t.Fatal("result failed") } } }
func TestSimpleLen(t *testing.T) { q := NewSimple(10, 1) for i := 0; i < NumJobsPrio; i++ { name := "test_" + strconv.FormatInt(int64(i), 10) prio, err := rand.Int63n(10, "go") if err != nil { t.Fatal(e.Trace(e.Forward(err))) } job := job.NewSimple(name, uint64(prio), func(i int) int { return i }, i) err = q.Add(job) if err != nil { t.Fatal(e.Trace(e.Forward(err))) } } if q.Len() != NumJobsPrio { t.Fatal("Len failed:", q.Len()) } }
func (d *Daemon) monitor() { go func() { d.monitoring = true var tries int unmonitor := true F: for { select { case <-time.After(d.Sleep): if d.Tries != 0 && tries > d.Tries+1 { d.monitoring = false if unmonitor { d.status.LogAndEmail(status.Normal, "", "Unmonitor daemon %v.", d.DaemonName) unmonitor = false continue F } continue F } d.changePid() if d.pid == -1 { d.status.LogAndEmail(status.Normal, "", "No pid file %v for %v.", d.PidFile, d.DaemonName) d.running = false } else { err := syscall.Kill(d.pid, 0) if err != nil && err.Error() == "no such process" { d.status.LogAndEmail(status.Normal, "", "%v process is gone.", d.DaemonName) d.running = false } else if err != nil { d.status.Log(status.Verbose, "Monitor failed for %v with error: %v", d.DaemonName, e.Trace(e.New(err))) d.running = false } else { d.running = true } } if d.running { err := d.ping() if e.Equal(err, ErrPingFailed) { d.running = false } else if err != nil && !e.Equal(err, ErrProtoNotSupported) && !e.Equal(err, ErrUrlIsEmpty) { d.status.Log(status.Verbose, "Monitor ping failed for %v with error: %v", d.DaemonName, e.Trace(e.Forward(err))) d.running = false } p, err := event.ProbeProcess(d.pid) if e.Equal(err, "process not found") { d.status.LogAndEmail(status.Normal, "", "%v process is gone.", d.DaemonName) d.running = false } else if err != nil { d.status.Log(status.Verbose, "ProbeCurrentProcess failed with error: %v", err) } else { d.SendEvent(p) } } if !d.running { tries++ rnd, err := rand.Chars(10, rand.NumberLetters, "go") if err != nil { d.status.Log(status.Verbose, "Can't generate the job name for %v. Error: %v", d.DaemonName, e.Trace(e.Forward(err))) continue } job := job.NewSimple(d.DaemonName+rnd, d.Prio, func() error { err := d.restartProcess() if err != nil { d.status.LogAndEmail(status.Normal, "", "Can't restart process %v.", d.DaemonName) return e.Forward(err) } return nil }) d.status.Log(status.Verbose, "Add job %v for %v to queue %v.", job.Name(), d.DaemonName, d.Prio) d.Queue.Add(job) d.status.Log(status.Verbose, "Waiting job %v return.", job.Name()) job.Returns(&err) if err != nil { continue } d.status.LogAndEmail(status.Normal, "", "Restart command sent to %v.", d.DaemonName) } else { d.status.Log(status.Verbose, "%v process is running.", d.DaemonName) tries = 0 } case <-d.killMonitor: d.status.Log(status.Normal, "Monitor %v stopped.", d.DaemonName) return } } }() }