ms-tester/internal/problems/delivery/grpc/handlers.go

171 lines
4 KiB
Go
Raw Normal View History

2024-10-09 18:55:16 +00:00
package grpc
2024-08-18 00:07:31 +00:00
import (
"context"
2024-10-05 16:05:29 +00:00
"git.sch9.ru/new_gate/models"
2024-08-18 00:07:31 +00:00
"git.sch9.ru/new_gate/ms-tester/internal/lib"
2024-10-09 18:55:16 +00:00
"git.sch9.ru/new_gate/ms-tester/internal/problems"
2024-08-18 00:07:31 +00:00
problemv1 "git.sch9.ru/new_gate/ms-tester/pkg/go/gen/proto/problem/v1"
2024-10-09 18:55:16 +00:00
"git.sch9.ru/new_gate/ms-tester/pkg/utils"
2024-08-18 00:07:31 +00:00
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"io"
2024-08-20 22:01:06 +00:00
"os"
2024-08-18 00:07:31 +00:00
)
2024-10-09 18:55:16 +00:00
type problemHandlers struct {
problemv1.UnimplementedProblemServiceServer
problemUC problems.ProblemUseCase
}
func (h *problemHandlers) CreateProblem(server problemv1.ProblemService_CreateProblemServer) error {
2024-08-18 00:07:31 +00:00
ctx := server.Context()
2024-10-09 18:55:16 +00:00
if err := h.problemUC.CanCreateProblem(ctx); err != nil {
2024-08-22 22:56:03 +00:00
return err
2024-08-18 00:07:31 +00:00
}
2024-08-20 11:18:23 +00:00
req, err := server.Recv() // receive problem
2024-08-18 00:07:31 +00:00
if err != nil {
2024-08-22 22:56:03 +00:00
return lib.TransportError(err, lib.ErrBadInput, "can't receive problem")
2024-08-18 00:07:31 +00:00
}
problem := req.GetProblem()
if problem == nil {
2024-08-22 22:56:03 +00:00
return lib.TransportError(nil, lib.ErrBadInput, "empty problem")
2024-08-18 00:07:31 +00:00
}
p := &models.Problem{
Name: lib.AsStringP(problem.Name),
Description: lib.AsStringP(problem.Description),
TimeLimit: lib.AsInt32P(problem.TimeLimit),
MemoryLimit: lib.AsInt32P(problem.MemoryLimit),
}
ch := readChunks(ctx, server)
2024-08-20 22:01:06 +00:00
err = writeChunks(ctx, ch) // temp stub
if err != nil {
return err // FIXME
}
2024-10-09 18:55:16 +00:00
id, err := h.problemUC.CreateProblem(ctx, p) // FIXME
2024-08-18 00:07:31 +00:00
if err != nil {
2024-08-22 22:56:03 +00:00
return err
2024-08-18 00:07:31 +00:00
}
err = server.SendAndClose(&problemv1.CreateProblemResponse{
Id: id,
})
if err != nil {
2024-08-22 22:56:03 +00:00
return lib.TransportError(err, lib.ErrBadInput, "can't send response")
2024-08-18 00:07:31 +00:00
}
return nil
}
2024-08-20 22:01:06 +00:00
func writeChunks(ctx context.Context, chunks <-chan []byte) error {
2024-08-22 22:56:03 +00:00
// use s3
2024-08-20 22:01:06 +00:00
// FIXME: use ctx?
f, err := os.Create("out.txt") // FIXME: uuidv4 as initial temp name?
if err != nil {
return err
}
defer f.Close()
var off int64 = 0
for chunk := range chunks {
_, err = f.WriteAt(chunk, off)
if err != nil {
return err
}
off += int64(len(chunk))
}
// TODO: rename file to its hash
return nil
}
2024-08-18 00:07:31 +00:00
func readChunks(ctx context.Context, server problemv1.ProblemService_CreateProblemServer) <-chan []byte {
ch := make(chan []byte)
go func() {
defer close(ch)
for {
select {
case <-ctx.Done():
return // FIXME
default:
req, err := server.Recv()
if err != nil {
if err == io.EOF {
return // FIXME
}
if status.Code(err) == codes.Canceled {
return // FIXME
}
continue
}
test := req.GetTest()
if test == nil {
return // FIXME
}
ch <- test.Chunk
}
}
}()
return ch
}
2024-10-09 18:55:16 +00:00
func (h *problemHandlers) ReadProblem(ctx context.Context, req *problemv1.ReadProblemRequest) (*problemv1.ReadProblemResponse, error) {
problem, err := h.problemUC.ReadProblemById(ctx, req.GetId())
2024-08-18 00:07:31 +00:00
if err != nil {
2024-08-22 22:56:03 +00:00
return nil, err
2024-08-18 00:07:31 +00:00
}
return &problemv1.ReadProblemResponse{
Problem: &problemv1.ReadProblemResponse_Problem{
Id: *problem.Id,
Name: *problem.Name,
Description: *problem.Description,
TimeLimit: *problem.TimeLimit,
MemoryLimit: *problem.MemoryLimit,
2024-10-09 18:55:16 +00:00
CreatedAt: utils.TimestampP(problem.CreatedAt),
UpdatedAt: utils.TimestampP(problem.UpdatedAt),
2024-08-18 00:07:31 +00:00
},
}, nil
}
2024-10-09 18:55:16 +00:00
//func (h *problemHandlers) UpdateProblem(ctx context.Context, req *problemv1.UpdateProblemRequest) (*emptypb.Empty, error) {
2024-08-18 00:07:31 +00:00
// problem := req.GetProblem()
// if problem == nil {
// return nil, status.Errorf(codes.Unknown, "") // FIXME
// }
// err := s.problemService.UpdateProblem(
// ctx,
// &models.Problem{
// Id: lib.AsInt32P(problem.Id),
// Name: problem.Name,
// Description: problem.Description,
// TimeLimit: problem.TimeLimit,
// MemoryLimit: problem.MemoryLimit,
// },
// )
// if err != nil {
// return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME
// }
//
// return &emptypb.Empty{}, nil
//}
2024-10-09 18:55:16 +00:00
func (h *problemHandlers) DeleteProblem(ctx context.Context, req *problemv1.DeleteProblemRequest) (*emptypb.Empty, error) {
err := h.problemUC.DeleteProblem(ctx, req.GetId())
2024-08-18 00:07:31 +00:00
if err != nil {
2024-08-22 22:56:03 +00:00
return nil, err
2024-08-18 00:07:31 +00:00
}
return &emptypb.Empty{}, nil
}