feat: rabbitMQ request

This commit is contained in:
Iron_Felix 2025-11-30 01:34:59 +03:00
parent a25a912ead
commit c6cebb0ed2
6 changed files with 125 additions and 1 deletions

View file

@ -16,6 +16,11 @@ paths:
schema: schema:
type: boolean type: boolean
default: true default: true
- name: ext_search
in: query
schema:
type: boolean
default: false
- name: word - name: word
in: query in: query
schema: schema:

View file

@ -178,6 +178,7 @@ type GetTitlesParams struct {
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"` Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
Sort *TitleSort `form:"sort,omitempty" json:"sort,omitempty"` Sort *TitleSort `form:"sort,omitempty" json:"sort,omitempty"`
SortForward *bool `form:"sort_forward,omitempty" json:"sort_forward,omitempty"` SortForward *bool `form:"sort_forward,omitempty" json:"sort_forward,omitempty"`
ExtSearch *bool `form:"ext_search,omitempty" json:"ext_search,omitempty"`
Word *string `form:"word,omitempty" json:"word,omitempty"` Word *string `form:"word,omitempty" json:"word,omitempty"`
// Status List of title statuses to filter // Status List of title statuses to filter
@ -337,6 +338,14 @@ func (siw *ServerInterfaceWrapper) GetTitles(c *gin.Context) {
return return
} }
// ------------- Optional query parameter "ext_search" -------------
err = runtime.BindQueryParameter("form", true, false, "ext_search", c.Request.URL.Query(), &params.ExtSearch)
if err != nil {
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter ext_search: %w", err), http.StatusBadRequest)
return
}
// ------------- Optional query parameter "word" ------------- // ------------- Optional query parameter "word" -------------
err = runtime.BindQueryParameter("form", true, false, "word", c.Request.URL.Query(), &params.Word) err = runtime.BindQueryParameter("form", true, false, "word", c.Request.URL.Query(), &params.Word)

View file

@ -8,6 +8,11 @@ get:
schema: schema:
type: boolean type: boolean
default: true default: true
- in: query
name: ext_search
schema:
type: boolean
default: false
- in: query - in: query
name: word name: word
schema: schema:
@ -21,7 +26,6 @@ get:
description: List of title statuses to filter description: List of title statuses to filter
style: form style: form
explode: false explode: false
- in: query - in: query
name: rating name: rating
schema: schema:

1
go.mod
View file

@ -36,6 +36,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/quic-go/qpack v0.5.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect github.com/quic-go/quic-go v0.54.0 // indirect
github.com/streadway/amqp v1.1.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect github.com/ugorji/go/codec v1.3.0 // indirect
go.uber.org/mock v0.5.0 // indirect go.uber.org/mock v0.5.0 // indirect

2
go.sum
View file

@ -73,6 +73,8 @@ github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQ
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM=
github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=

103
modules/backend/rabbit.go Normal file
View file

@ -0,0 +1,103 @@
package main
import (
"context"
"encoding/json"
"fmt"
oapi "nyanimedb/api"
"time"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"github.com/streadway/amqp"
)
type RabbitRequest struct {
Name string `json:"name"`
Status oapi.TitleStatus `json:"titlestatus,omitempty"`
Rating float64 `json:"titleraring,omitempty"`
Year int32 `json:"year,omitempty"`
Season oapi.ReleaseSeason `json:"season,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
// PublishAndAwaitReply отправляет запрос и ждёт ответа от workerа.
// Возвращает раскодированный ответ или ошибку.
func PublishAndAwaitReply(
ctx context.Context,
ch *amqp.Channel,
requestQueue string, // например: "svc.media.process.requests"
request RabbitRequest, // ваша структура запроса
replyCh chan<- any, // куда положить ответ (вы читаете извне)
) error {
// 1. Создаём временную очередь для ответов
replyQueue, err := ch.QueueDeclare(
"", // auto-generated name
false, // not durable
true, // exclusive
true, // auto-delete
false, // no-wait
nil,
)
if err != nil {
return fmt.Errorf("failed to declare reply queue: %w", err)
}
// 2. Готовим корреляционный ID
corrID := uuid.New().String() // ← используйте github.com/google/uuid
logrus.Infof("New CorrID: %s", corrID)
// 3. Сериализуем запрос
body, err := json.Marshal(request)
if err != nil {
return fmt.Errorf("failed to marshal request: %w", err)
}
// 4. Публикуем запрос
err = ch.Publish(
"", // default exchange (или свой, если используете)
requestQueue,
false,
false,
amqp.Publishing{
ContentType: "application/json",
CorrelationId: corrID,
ReplyTo: replyQueue.Name,
DeliveryMode: amqp.Persistent,
Timestamp: time.Now(),
Body: body,
},
)
if err != nil {
return fmt.Errorf("failed to publish request, corrID: %s : %w", corrID, err)
}
// 5. Подписываемся на ответы
msgs, err := ch.Consume(
replyQueue.Name,
"", // consumer tag
true, // auto-ack
true, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
return fmt.Errorf("failed to consume from reply queue: %w", err)
}
// 6. Ожидаем ответ с таймаутом
select {
case msg := <-msgs:
if msg.CorrelationId != corrID {
return fmt.Errorf("correlation ID mismatch: got %s, expected %s", msg.CorrelationId, corrID)
}
// Десериализуем — тут можно передать target-структуру или использовать interface{}
// В данном случае просто возвращаем байты или пусть вызывающая сторона парсит
replyCh <- msg.Body // или json.Unmarshal → и отправить структуру в канал
return nil
case <-ctx.Done():
return ctx.Err()
}
}