Example #1
0
func validateGetCapacityRequest(p *pb.GetCapacityRequest) error {
	if p.GetClientId() == "" {
		return errors.New("client_id cannot be empty")
	}
	seen := make(map[string]bool)
	for _, r := range p.Resource {
		if err := validateResourceRequest(r); err != nil {
			return err
		}
		seen[r.GetResourceId()] = true
	}

	return nil
}
Example #2
0
// GetCapacity assigns capacity leases to clients. It is part of the
// doorman.CapacityServer implementation.
func (server *Server) GetCapacity(ctx context.Context, in *pb.GetCapacityRequest) (out *pb.GetCapacityResponse, err error) {
	out = new(pb.GetCapacityResponse)

	log.V(2).Infof("GetCapacity req: %v", in)

	start := time.Now()
	requests.WithLabelValues("GetCapacity").Inc()
	defer func() {
		log.V(2).Infof("GetCapacity res: %v", out)
		requestDurations.WithLabelValues("GetCapacity").Observe(time.Since(start).Seconds())
		if err != nil {
			requestErrors.WithLabelValues("GetCapacity").Inc()
		}
	}()

	// If we are not the master, we redirect the client.
	if !server.IsMaster() {
		master := server.CurrentMaster()
		out.Mastership = &pb.Mastership{}

		if master != "" {
			out.Mastership.MasterAddress = proto.String(master)
		}
		return out, nil
	}

	client := in.GetClientId()

	// We will create a new goroutine for every resource in the
	// request. This is the channel that the leases come back on.
	itemsC := make(chan item, len(in.Resource))

	// requests will keep information about all resource requests that
	// the specified client sent at the moment.
	var requests []clientRequest

	for _, req := range in.Resource {
		request := clientRequest{
			client:     client,
			resID:      req.GetResourceId(),
			has:        req.GetHas().GetCapacity(),
			wants:      req.GetWants(),
			subclients: 1,
		}

		requests = append(requests, request)
	}

	server.getCapacity(requests, itemsC)

	// We collect the assigned leases.
	for range in.Resource {
		item := <-itemsC
		resp := &pb.ResourceResponse{
			ResourceId: proto.String(item.id),
			Gets: &pb.Lease{
				RefreshInterval: proto.Int64(int64(item.lease.RefreshInterval.Seconds())),
				ExpiryTime:      proto.Int64(item.lease.Expiry.Unix()),
				Capacity:        proto.Float64(item.lease.Has),
			},
		}
		server.getOrCreateResource(item.id).SetSafeCapacity(resp)
		out.Response = append(out.Response, resp)
	}

	return out, nil
}