diff --git a/apps/iris/src/connector/rabbitmq/connector.go b/apps/iris/src/connector/rabbitmq/connector.go index 28d61efd55..536d3a3781 100644 --- a/apps/iris/src/connector/rabbitmq/connector.go +++ b/apps/iris/src/connector/rabbitmq/connector.go @@ -8,6 +8,7 @@ import ( amqp "github.com/rabbitmq/amqp091-go" instrumentation "github.com/skkuding/codedang/apps/iris/src" "github.com/skkuding/codedang/apps/iris/src/router" + "github.com/skkuding/codedang/apps/iris/src/router/response" "github.com/skkuding/codedang/apps/iris/src/service/logger" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" @@ -88,10 +89,10 @@ func (c *connector) handle(message amqp.Delivery, ctx context.Context) { resultChan := make(chan []byte) if message.Type == "" { - resultChan <- router.NewResponse("", nil, fmt.Errorf("type(message property) must not be empty")).Marshal() + resultChan <- response.NewJudgeResponse("", nil, fmt.Errorf("type(message property) must not be empty")).Marshal() close(resultChan) } else if message.MessageId == "" { - resultChan <- router.NewResponse("", nil, fmt.Errorf("message_id(message property) must not be empty")).Marshal() + resultChan <- response.NewJudgeResponse("", nil, fmt.Errorf("message_id(message property) must not be empty")).Marshal() close(resultChan) } else { go c.router.Route(message.Type, message.MessageId, message.Body, resultChan, spanCtx) diff --git a/apps/iris/src/router/response.go b/apps/iris/src/router/response/judge.go similarity index 79% rename from apps/iris/src/router/response.go rename to apps/iris/src/router/response/judge.go index 82ec2a596c..c7de46182e 100644 --- a/apps/iris/src/router/response.go +++ b/apps/iris/src/router/response/judge.go @@ -1,7 +1,6 @@ -package router +package response import ( - "bytes" "encoding/json" "errors" "strconv" @@ -9,14 +8,15 @@ import ( "github.com/skkuding/codedang/apps/iris/src/handler" ) -type Response struct { +type JudgeResponse struct { SubmissionId int `json:"submissionId"` JudgeResultCode handler.ResultCode `json:"resultCode"` JudgeResult json.RawMessage `json:"judgeResult"` + Finished bool `json:"finished"` Error string `json:"error"` } -func NewResponse(id string, data json.RawMessage, err error) *Response { +func NewJudgeResponse(id string, data json.RawMessage, err error) *JudgeResponse { resultCode := handler.ACCEPTED errMessage := "" @@ -30,24 +30,16 @@ func NewResponse(id string, data json.RawMessage, err error) *Response { } _id, _ := strconv.Atoi(id) - return &Response{ + return &JudgeResponse{ SubmissionId: _id, JudgeResultCode: resultCode, JudgeResult: data, Error: errMessage, + Finished: false, } } -func JSONMarshal(t interface{}) ([]byte, error) { - // source: https://stackoverflow.com/questions/28595664/how-to-stop-json-marshal-from-escaping-and - buffer := &bytes.Buffer{} - encoder := json.NewEncoder(buffer) - encoder.SetEscapeHTML(false) - err := encoder.Encode(t) - return buffer.Bytes(), err -} - -func (r *Response) Marshal() []byte { +func (r *JudgeResponse) Marshal() []byte { if res, err := JSONMarshal(r); err != nil { // Error on marshaling router response means that diff --git a/apps/iris/src/router/response/response.go b/apps/iris/src/router/response/response.go new file mode 100644 index 0000000000..54b903faa9 --- /dev/null +++ b/apps/iris/src/router/response/response.go @@ -0,0 +1,19 @@ +package response + +import ( + "bytes" + "encoding/json" +) + +type Response interface { + Marshal() []byte +} + +func JSONMarshal(t interface{}) ([]byte, error) { + // source: https://stackoverflow.com/questions/28595664/how-to-stop-json-marshal-from-escaping-and + buffer := &bytes.Buffer{} + encoder := json.NewEncoder(buffer) + encoder.SetEscapeHTML(false) + err := encoder.Encode(t) + return buffer.Bytes(), err +} diff --git a/apps/iris/src/router/response/submission.go b/apps/iris/src/router/response/submission.go new file mode 100644 index 0000000000..80e4011858 --- /dev/null +++ b/apps/iris/src/router/response/submission.go @@ -0,0 +1,37 @@ +package response + +import ( + "strconv" +) + +type SubmissionResponse struct { + SubmissionId int `json:"submissionId"` + JudgeResults []*JudgeResponse `json:"judgeResults"` + Finished bool `json:"finished"` +} + +func NewSubmissionResponse(id string, judgeResponses []*JudgeResponse) *SubmissionResponse { + // TODO: JudgeResponse 가공하기 + + _id, _ := strconv.Atoi(id) + return &SubmissionResponse{ + SubmissionId: _id, + JudgeResults: judgeResponses, + Finished: true, + } +} + +func (r *SubmissionResponse) formatJudgeResponse(res *JudgeResponse) {} + +func (r *SubmissionResponse) Marshal() []byte { + + if res, err := JSONMarshal(r); err != nil { + // Error on marshaling router response means that + // the process cannot send valid response data + // because some logic is incorrect. + // So, panic without recover because debugging is needed + panic(err) + } else { + return res + } +} diff --git a/apps/iris/src/router/router.go b/apps/iris/src/router/router.go index 7f6e5a1595..3fe807c879 100644 --- a/apps/iris/src/router/router.go +++ b/apps/iris/src/router/router.go @@ -7,6 +7,7 @@ import ( instrumentation "github.com/skkuding/codedang/apps/iris/src" "github.com/skkuding/codedang/apps/iris/src/handler" + "github.com/skkuding/codedang/apps/iris/src/router/response" "github.com/skkuding/codedang/apps/iris/src/service/logger" "github.com/skkuding/codedang/apps/iris/src/service/testcase" "go.opentelemetry.io/otel" @@ -79,15 +80,22 @@ func (r *router[C, E]) Route(path string, id string, data []byte, out chan []byt default: err := fmt.Errorf("invalid request type: %s", path) r.errHandle(err) - out <- NewResponse(id, nil, err).Marshal() + out <- response.NewJudgeResponse(id, nil, err).Marshal() } + judgeResult := make([]*response.JudgeResponse, 0) + for result := range judgeChan { r.errHandle(result.Err) - out <- NewResponse(id, result.Result, result.Err).Marshal() + res := response.NewJudgeResponse(id, result.Result, result.Err) + out <- res.Marshal() + judgeResult = append(judgeResult, res) // break } - // return NewResponse(id, handlerResult, err).Marshal() + + out <- response.NewSubmissionResponse(id, judgeResult).Marshal() + + // return response.NewJudgeResponse(id, handlerResult, err).Marshal() close(out) r.logger.Log(logger.DEBUG, "Router done...") }