예제 #1
0
파일: claim.go 프로젝트: logan/heim
func Claim(ctx scope.Context, jq JobQueue, handlerID string, pollTime time.Duration, stealChance float64) (*Job, error) {
	for ctx.Err() == nil {
		if rand.Float64() < stealChance {
			job, err := jq.TrySteal(ctx, handlerID)
			if err != nil && err != ErrJobNotFound {
				return nil, err
			}
			if err == nil {
				return job, nil
			}
		}
		job, err := jq.TryClaim(ctx, handlerID)
		if err != nil {
			if err == ErrJobNotFound {
				child := ctx.ForkWithTimeout(pollTime)
				if err = jq.WaitForJob(child); err != nil && err != scope.TimedOut {
					return nil, err
				}
				continue
			}
			return nil, err
		}
		return job, nil
	}
	return nil, ctx.Err()
}
예제 #2
0
func (c *Controller) processOne(ctx scope.Context) error {
	job, err := c.claimOrSteal(ctx.ForkWithTimeout(StatsInterval))
	if err != nil {
		if err == scope.TimedOut {
			return nil
		}
		return err
	}

	if job.Type != jobs.EmailJobType {
		return jobs.ErrInvalidJobType
	}

	payload, err := job.Payload()
	if err != nil {
		return err
	}

	return job.Exec(ctx, func(ctx scope.Context) error {
		labels := prometheus.Labels{"queue": c.jq.Name()}
		defer processedCounter.With(labels).Inc()
		if err := c.w.Work(ctx, job, payload); err != nil {
			failedCounter.With(labels).Inc()
			return err
		}
		completedCounter.With(labels).Inc()
		return nil
	})
}
예제 #3
0
파일: jobs.go 프로젝트: bramvdbogaerde/heim
func (j *Job) Exec(ctx scope.Context, f func(scope.Context) error) error {
	if j.JobClaim == nil {
		return ErrJobNotClaimed
	}

	w := io.MultiWriter(os.Stdout, j)
	prefix := fmt.Sprintf("[%s-%s] ", j.Queue.Name(), j.HandlerID)
	deadline := time.Now().Add(j.MaxWorkDuration)
	child := logging.LoggingContext(ctx.ForkWithTimeout(j.MaxWorkDuration), w, prefix)
	if err := f(child); err != nil {
		if err != scope.TimedOut {
			delay := time.Duration(j.AttemptsMade+1) * BackoffDuration
			if time.Now().Add(delay).After(deadline) {
				delay = deadline.Sub(time.Now())
			}
			time.Sleep(delay)
		}
		if ferr := j.Fail(ctx, err.Error()); ferr != nil {
			return ferr
		}
		return err
	}

	if err := j.Complete(ctx); err != nil {
		return err
	}

	return nil
}