Esempio n. 1
0
func (e *Engine) Serve(ctx context.Context) error {
	pools := make([]*UserPool, 0, len(e.cfg.Pools))
	for _, upc := range e.cfg.Pools {
		up, err := NewUserPoolFromConfig(&upc)
		if err != nil {
			log.Printf("Could not create user pool: %s", err)
			continue
		}
		pools = append(pools, up)
	}
	promises := utils.Promises{}
	for _, up := range pools {
		promises = append(promises, utils.PromiseCtx(ctx, up.Start))
	}
	select {
	case err := <-promises.All():
		if err != nil {
			return err
		}
	case <-ctx.Done():
	}
	log.Println("Done")
	return nil
}
Esempio n. 2
0
func (up *UserPool) Start(ctx context.Context) error {
	// userCtx will be canceled when all users finished their execution

	userCtx, resultCancel := context.WithCancel(ctx)

	userPromises := utils.Promises{}
	utilsPromises := utils.Promises{
		utils.PromiseCtx(ctx, up.ammunition.Start),
		utils.PromiseCtx(userCtx, up.results.Start),
		utils.PromiseCtx(ctx, up.startupLimiter.Start),
	}
	var sharedLimiter limiter.Limiter

	if up.sharedSchedule {
		var err error
		sharedLimiter, err = GetLimiter(up.userLimiterConfig)
		if err != nil {
			return fmt.Errorf("could not make a user limiter from config due to %s", err)
		}
		// Starting shared limiter.
		// This may cause spike load in the beginning of a test if it takes time
		// to initialize a user, because we don't wait for them to initialize in
		// case of shared limiter and there might be some ticks accumulated
		utilsPromises = append(utilsPromises, utils.PromiseCtx(userCtx, sharedLimiter.Start))
	}

	for range up.startupLimiter.Control() {
		var l limiter.Limiter
		if up.sharedSchedule {
			l = sharedLimiter
		} else {
			var err error
			l, err = GetLimiter(up.userLimiterConfig)
			if err != nil {
				return fmt.Errorf("could not make a user limiter from config due to %s", err)
			}
		}
		g, err := GetGun(up.gunConfig)
		if err != nil {
			return fmt.Errorf("could not make a gun from config due to %s", err)
		}
		u := &User{
			Name:       up.name,
			Ammunition: up.ammunition,
			Results:    up.results,
			Limiter:    l,
			Gun:        g,
		}
		if !up.sharedSchedule {
			utilsPromises = append(utilsPromises, utils.PromiseCtx(userCtx, l.Start))
		}
		userPromises = append(userPromises, utils.PromiseCtx(ctx, u.Run))
	}
	// FIXME: wrong logic here
	log.Println("Started all users. Waiting for them")
	err := <-userPromises.All()
	resultCancel() // stop result listener when all users finished

	err2 := utilsPromises.All()
	if err2 != nil {
		fmt.Printf("%v", err2)
	}
	return err
}