func main() { flag.Parse() var tb *beanstalk.TubeSet var conn_bs *beanstalk.Conn rs_timeout := time.Duration(Settings.BeanstalkdReserveTimeout) fail_wait := time.Duration(Settings.FailWait) * time.Second conn_bs, e := beanstalk.Dial("tcp", Settings.BeanstalkdAddr) if e != nil { log.Fatal("failed to connected to beanstalkd", e) } tb = beanstalk.NewTubeSet(conn_bs, Settings.BeanstalkdTube) for { // reserve a job id, job, e := tb.Reserve(rs_timeout) // timeout is valid, anything else is fatal if cerr, ok := e.(beanstalk.ConnError); ok && cerr.Err == beanstalk.ErrTimeout { time.Sleep(fail_wait) continue } else if e != nil { log.Fatal("failed to reserve job", e) } else { log.Println("read job id", id, "size", len(job), "bytes") } // connect to the gor replay server conn_gr, e := net.Dial("tcp", Settings.GorReplayAddr) if e != nil { log.Fatal("failed to connected to gor replay server", e) time.Sleep(fail_wait) } // write to gor replay server w, e := conn_gr.Write(job) if e != nil { log.Fatal("failed to write to", Settings.GorReplayAddr, "error", e) } else { log.Println("wrote", w, "bytes to", Settings.GorReplayAddr) } // close connection to gor replay server conn_gr.Close() // delete the job e = conn_bs.Delete(id) if e != nil { log.Println("failed to delete job id", id, "error", e) } } }
// reserve-with-timeout until there's a job or something panic-worthy. // Handles beanstalk.ErrTimeout by retrying immediately. // Handles beanstalk.ErrDeadline by sleeping DeadlineSoonDelay before retry. // panics for other errors. func MustReserveWithoutTimeout(ts *beanstalk.TubeSet) (id uint64, body []byte) { var err error for { id, body, err = ts.Reserve(1 * time.Hour) if err == nil { return } else if err.(beanstalk.ConnError).Err == beanstalk.ErrTimeout { continue } else if err.(beanstalk.ConnError).Err == beanstalk.ErrDeadline { time.Sleep(DeadlineSoonDelay) continue } else { panic(err) } } }
// Satisfies the Source interface. Begins listening to an AWS SQS queue. If no // message is on the queue it sleeps for a set period of time before trying again func (this *Beanstalkd) Listen(wg sync.WaitGroup) { sCon := fmt.Sprintf("%s:%d", this.Host, this.Port) this.Log.Info("Start listening (beanstalkd:%s)", sCon) c, err := beanstalk.Dial("tcp", sCon) if err != nil { this.Log.Error("Could not listen on %s: %s", sCon, err.Error()) wg.Done() return } defer c.Close() timeout := true var tubeSet *beanstalk.TubeSet for { if timeout { tube := this.selectTubes(c) if tube == nil { time.Sleep(time.Second * 5) continue } tubeSet = beanstalk.NewTubeSet(c, tube.Name) } this.Log.Debug("Watching %v", tubeSet.Name) id, body, err := tubeSet.Reserve(time.Second * 5) if err != nil { timeout = true continue } else { timeout = false } this.handle(id, body, c) } wg.Done() }