in projects/gke-optimization/binpacker/api/pkg/interface/handler/binpacking.go [70:151]
func (bh binpackingHandler) Calculate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
m := protojson.MarshalOptions{
EmitUnpopulated: true,
}
body, err := io.ReadAll(r.Body)
if err != nil {
calculateErrorResponse(w, m, "failed to read request json", err.Error(), err)
return
}
var request pb.BinpackingCalculateRequest
err = protojson.Unmarshal(body, &request)
if err != nil {
calculateErrorResponse(w, m, "invalid data provided", err.Error(), err)
return
}
if len(request.Workloads) == 0 {
calculateErrorResponse(w, m, "invalid data provided", "no workload provided", err)
return
}
if request.MinNumNodes == 0 {
request.MinNumNodes = 1
}
metrics := extractMetrics(&request)
ctx := context.Background()
solution, err := bh.binpackingUsecase.Calculate(
ctx,
metrics.CPURequests,
metrics.CPULimits,
metrics.MemoryRequests,
metrics.MemoryLimits,
metrics.MinNumNode,
)
if err != nil {
calculateErrorResponse(w, m, "failed to find solution", err.Error(), err)
return
}
response, err := m.Marshal(&pb.BinpackingCalculateResponse{
Recommendation: &pb.BinpackingRecommendation{
Cpu: float64(solution.Recommendation.CPU),
Memory: float64(solution.Recommendation.MemoryInGiB),
NumNodes: int32(solution.Recommendation.NumNodes),
},
RequestDetail: &pb.BinpackingRequestDetail{
TotalCpuRequest: float64(solution.Rationale.CPU.TotalCPURequest),
MaxCpuLimit: float64(solution.Rationale.CPU.MaxCPULimit),
TotalMemoryRequest: int64(solution.Rationale.Memory.TotalMemoryRequest),
MaxMemoryLimit: int64(solution.Rationale.Memory.MaxMemoryLimit),
},
RecommendationBreakdown: &pb.RecommendationBreakdown{
Cpu: &pb.CpuBreakdown{
NodeSize: float64(solution.Recommendation.CPU),
Reserved: float64(solution.Rationale.CPU.Reserved),
SystemUsage: float64(solution.Rationale.CPU.SystemResourcesUsage),
CapacityUserWorkloads: float64(solution.Rationale.CPU.CapacityUserWorkloads),
},
Memory: &pb.MemoryBreakdown{
NodeSize: int64(node.GiBToBytes(solution.Recommendation.MemoryInGiB)),
KernelUsage: int64(solution.Rationale.Memory.KernelUsage),
Reserved: int64(solution.Rationale.Memory.Reserved),
EvictionThreshold: int64(solution.Rationale.Memory.EvictionThreshold),
SystemUsage: int64(solution.Rationale.Memory.SystemResourcesUsage),
CapacityUserWorkloads: int64(solution.Rationale.Memory.CapacityUserWorkloads),
},
},
})
if err != nil {
calculateErrorResponse(w, m, "failed to encode json", err.Error(), err)
return
}
w.Header().Set("Content-Type", "application/json")
_, writeErr := w.Write(response)
if writeErr != nil {
glog.Errorf("Failed to write response: %s", response)
}
}