Example #1
0
// Return is used to return resource to pool group
func (p *Group) Return(ctx context.Context, res Resource, forceClose bool) error {

	if res == nil {
		log.Errorf(ctx, "Return pool conn is null")
		return nil
	}

	pool, err := p.findPool(res.Address())
	if err != nil {
		log.Errorf(ctx, "Return pool conn can't found pool to them and close conn, address: %s", res.Address())
		res.Close()
	}

	pool.Put(ctx, res, forceClose)

	return nil

}
Example #2
0
func (r *ResourcePool) closeConn(ctx context.Context, resource Resource) {

	if resource == nil {
		return
	}

	err := resource.RawClose()
	if err != nil {
		log.Errorf(ctx, "Close connection but failured, address: %s", r.address)
	}
	log.Infof(ctx, "Close resource: %s", resource.Address())

}
Example #3
0
// Get is used to get resource form group pool
func (p *Group) Get(ctx context.Context) (Resource, error) {
	pool, _, err := p.selectPool(ctx)
	if err == nil {
		return nil, err
	}
	res, err := pool.Get(ctx)
	if err != nil {
		log.Errorf(ctx, "Select pool failure, error: %v", err)
		return nil, err
	}
	log.Infof(ctx, "Selected pool %s with %d\n", res.Address())
	return res, nil
}
Example #4
0
// enqueue is used to do real enqueue op
func (r *ResourcePool) enqueue(ctx context.Context, res Resource) {

	if r.address != res.Address() {
		log.Errorf(ctx, "FATAL: Conn %s back to wrong pool %s\n", r.address, res.Address())
	}

	start := time.Now()
	log.Infof(ctx, "Start enqueue, address: %s, av-size: %d\n", res.Address(), len(r.resources))
	select {
	case r.resources <- resourceWrapper{res, time.Now()}:
		log.Infof(ctx, "Put resource back, address: %s, av-size: %d,  waste-time: %d\n", res.Address(), len(r.resources), time.Now().Sub(start).Nanoseconds())
		return
	default:
		log.Warningf(ctx, "Put resource back failure, because full close it, address: %s, waste-time: %d\n", res.Address(), len(r.resources))
		r.closeConn(ctx, res)
	}

}
Example #5
0
// Get resource from pool
func (r *ResourcePool) get(ctx context.Context, wait bool) (Resource, error) {

	select {
	case <-ctx.Done():
		return nil, ErrTimeout
	default:
	}

	var (
		wrapper resourceWrapper
		err     error
	)

	start := time.Now()
	for {
		select {
		case wrapper = <-r.resources:
			if time.Now().Sub(wrapper.timeUsed) >= r.idleTimeout {
				log.Warningf(ctx, "Get idle timeout resource, address: %s, av-size: %d,  waste-time: %d\n", wrapper.resource.Address(), len(r.resources), time.Now().Sub(start).Nanoseconds())
				r.closeConn(ctx, wrapper.resource)
				continue
			}
			log.Infof(ctx, "Get resouce from pool success, address: %v, av-size: %d,  waste-time: %d\n", wrapper.resource.Address(), len(r.resources), time.Now().Sub(start).Nanoseconds())
			return wrapper.resource, nil
		default:
			log.Warningf(ctx, "Have not enough resource in pool, start create resource, address: %s, av-size: %d\n", r.address, len(r.resources))
			var res Resource
			if res, err = r.factory(); err != nil {
				log.Errorf(ctx, "create resource failure, error: %v", err)
				return nil, err
			}
			log.Infof(ctx, "Create new resource successed, address: %s", res.Address())

			r.enqueue(ctx, res)

			log.Infof(ctx, "New resource back to queue sucessed, address: %s, av-size: %d", res.Address(), len(r.resources))

			continue
		}
	}
}