Compare commits
10 commits
e5713dd67e
...
6867d2d74e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6867d2d74e | ||
|
|
5e1017df69 | ||
|
|
850fb38e16 | ||
|
|
2ada5e5a9e | ||
|
|
4759e7638c | ||
|
|
a4097706de | ||
|
|
7dd4a6830e | ||
|
|
62337d3943 | ||
|
|
9a83bac140 | ||
|
|
392cdbfd4d |
23 changed files with 1073 additions and 68 deletions
6
.dockerignore
Normal file
6
.dockerignore
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.idea
|
||||
.git
|
||||
.gitignore
|
||||
api.env
|
||||
gen-swag.sh
|
||||
migrations.sql
|
||||
31
.forgejo/workflows/make-image.yml
Normal file
31
.forgejo/workflows/make-image.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+*'
|
||||
|
||||
env:
|
||||
IMAGE_NAME: repo-app
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: Make image
|
||||
runs-on: docker
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to Docker Registry
|
||||
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login repo.nqws.ru -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
|
||||
|
||||
- name: Extract version from tag
|
||||
id: extract_version
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
|
||||
- name: Make image
|
||||
run: |
|
||||
docker buildx build --platform linux/amd64 \
|
||||
--tag repo.nqws.ru/merch-tracker/repo-app-v2:latest \
|
||||
--tag repo.nqws.ru/merch-tracker/repo-app-v2:${{ env.VERSION }} \
|
||||
--push .
|
||||
34
Dockerfile
Normal file
34
Dockerfile
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
FROM golang:1.25.1-alpine3.22 AS builder
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
curl \
|
||||
git \
|
||||
ca-certificates
|
||||
|
||||
|
||||
RUN apk add --no-cache tzdata
|
||||
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd
|
||||
|
||||
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
curl \
|
||||
ca-certificates \
|
||||
tzdata
|
||||
|
||||
COPY --from=builder /app/main /usr/local/bin/app
|
||||
|
||||
|
||||
RUN chmod +x /usr/local/bin/app
|
||||
RUN adduser -D -s /bin/bash appuser
|
||||
USER appuser
|
||||
|
||||
ENTRYPOINT ["app"]
|
||||
3
api.env
3
api.env
|
|
@ -5,6 +5,9 @@ APP_API_PREFIX=/api/v2
|
|||
APP_GIN_MODE=development
|
||||
APP_ALLOWED_ORIGINS=http://localhost:5173,
|
||||
|
||||
GRPC_SERVER_PORT=9050
|
||||
GRPC_CLIENT_PORT=9060
|
||||
|
||||
DB_HOST=
|
||||
DB_PORT=
|
||||
DB_USER=
|
||||
|
|
|
|||
18
cmd/main.go
18
cmd/main.go
|
|
@ -8,6 +8,7 @@ import (
|
|||
"merch-parser-api/internal/api/merch"
|
||||
"merch-parser-api/internal/api/user"
|
||||
"merch-parser-api/internal/app"
|
||||
"merch-parser-api/internal/grpcService"
|
||||
"merch-parser-api/internal/interfaces"
|
||||
"merch-parser-api/internal/provider/auth"
|
||||
"merch-parser-api/internal/provider/token"
|
||||
|
|
@ -66,6 +67,10 @@ func main() {
|
|||
})
|
||||
log.Debug("Auth provider initialized")
|
||||
|
||||
tasksRepo := merch.NewTaskRepository(database)
|
||||
tasksProvider := merch.NewTaskProvider(tasksRepo)
|
||||
grpcServer := grpcService.NewGrpcServer(tasksProvider)
|
||||
|
||||
//register app modules
|
||||
users := user.NewHandler(user.Deps{
|
||||
Auth: authProvider,
|
||||
|
|
@ -87,11 +92,14 @@ func main() {
|
|||
|
||||
//keep last
|
||||
appl := app.NewApp(app.Deps{
|
||||
Host: c.AppConf.Host,
|
||||
Port: c.AppConf.Port,
|
||||
ApiPrefix: c.AppConf.ApiPrefix,
|
||||
RouterHandler: routerHandler,
|
||||
Modules: modules,
|
||||
Host: c.AppConf.Host,
|
||||
Port: c.AppConf.Port,
|
||||
ApiPrefix: c.AppConf.ApiPrefix,
|
||||
RouterHandler: routerHandler,
|
||||
Modules: modules,
|
||||
GrpcServer: grpcServer,
|
||||
GrpcServerPort: c.GrpcConf.GrpcServerPort,
|
||||
GrpcClientPort: c.GrpcConf.GrpcClientPort,
|
||||
})
|
||||
|
||||
err = appl.Run(ctx)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ package config
|
|||
import "strings"
|
||||
|
||||
type Config struct {
|
||||
AppConf AppConfig
|
||||
DBConf DatabaseConfig
|
||||
JWTConf JWTConfig
|
||||
AppConf AppConfig
|
||||
DBConf DatabaseConfig
|
||||
JWTConf JWTConfig
|
||||
GrpcConf GrpcConfig
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
|
|
@ -34,6 +35,11 @@ type JWTConfig struct {
|
|||
RefreshExpire string
|
||||
}
|
||||
|
||||
type GrpcConfig struct {
|
||||
GrpcServerPort string
|
||||
GrpcClientPort string
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
AppConf: AppConfig{
|
||||
|
|
@ -61,5 +67,10 @@ func NewConfig() *Config {
|
|||
AccessExpire: getEnv("JWT_ACCESS_EXPIRE", ""),
|
||||
RefreshExpire: getEnv("JWT_REFRESH_EXPIRE", ""),
|
||||
},
|
||||
|
||||
GrpcConf: GrpcConfig{
|
||||
GrpcServerPort: getEnv("GRPC_SERVER_PORT", ""),
|
||||
GrpcClientPort: getEnv("GRPC_CLIENT_PORT", ""),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -12,6 +12,8 @@ require (
|
|||
github.com/swaggo/gin-swagger v1.6.1
|
||||
github.com/swaggo/swag v1.16.6
|
||||
golang.org/x/crypto v0.42.0
|
||||
google.golang.org/grpc v1.75.1
|
||||
google.golang.org/protobuf v1.36.9
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
gorm.io/gorm v1.31.0
|
||||
)
|
||||
|
|
@ -66,5 +68,5 @@ require (
|
|||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
google.golang.org/protobuf v1.36.9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
|
||||
)
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -173,6 +173,12 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
|
|||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
|||
|
|
@ -134,16 +134,16 @@ func (co *controller) getAllMerch(c *gin.Context) {
|
|||
// @Description Обновить информацию про мерч по его uuid в json-е
|
||||
// @Tags Merch
|
||||
// @Security BearerAuth
|
||||
// @Param body body MerchDTO true "merch_uuid"
|
||||
// @Success 200 {object} MerchDTO
|
||||
// @Param body body UpdateMerchDTO true "merch_uuid"
|
||||
// @Success 200
|
||||
// @Failure 400 {object} responses.ErrorResponse400
|
||||
// @Failure 500 {object} responses.ErrorResponse500
|
||||
// @Router /merch/{uuid} [put]
|
||||
// @Router /merch/ [put]
|
||||
func (co *controller) updateMerch(c *gin.Context) {
|
||||
var payload MerchDTO
|
||||
var payload UpdateMerchDTO
|
||||
if err := c.ShouldBind(&payload); err != nil {
|
||||
c.JSON(http.StatusBadRequest, responses.ErrorResponse400{Error: err.Error()})
|
||||
log.WithError(err).Error("Merch | Failed to bind JSON on add merch")
|
||||
log.WithError(err).Error("Merch | Failed to bind JSON on update merch")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,3 +46,10 @@ type PricesResponse struct {
|
|||
MerchUuid string `json:"merch_uuid"`
|
||||
Origins []OriginWithPrices `json:"origins"`
|
||||
}
|
||||
|
||||
type UpdateMerchDTO struct {
|
||||
MerchUuid string `json:"merch_uuid"`
|
||||
Name string `json:"name"`
|
||||
Origin string `json:"origin"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@ func (Merch) TableName() string {
|
|||
}
|
||||
|
||||
type Surugaya struct {
|
||||
Id uint `gorm:"primary_key" json:"-"`
|
||||
DeletedAt sql.NullTime `json:"-"`
|
||||
MerchUuid string `json:"-"`
|
||||
Link string `json:"link"`
|
||||
CookieValues string `json:"cookie_values"`
|
||||
Id uint `gorm:"primary_key" json:"-"`
|
||||
DeletedAt sql.NullTime `json:"-"`
|
||||
MerchUuid string `json:"-"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
func (Surugaya) TableName() string {
|
||||
|
|
|
|||
93
internal/api/merch/provider.go
Normal file
93
internal/api/merch/provider.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
package merch
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"merch-parser-api/internal/shared"
|
||||
)
|
||||
|
||||
type Link struct {
|
||||
Surugaya []Surugaya
|
||||
Mandarake []Mandarake
|
||||
}
|
||||
|
||||
type TaskProvider struct {
|
||||
repo TaskRepository
|
||||
}
|
||||
|
||||
type TaskRepository interface {
|
||||
GetLinks() (*Link, error)
|
||||
InsertPrices() error
|
||||
}
|
||||
|
||||
type TaskRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewTaskProvider(repo TaskRepository) *TaskProvider {
|
||||
return &TaskProvider{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTaskRepository(db *gorm.DB) TaskRepository {
|
||||
return &TaskRepo{db: db}
|
||||
}
|
||||
|
||||
func (p *TaskProvider) PrepareTasks() (map[string]shared.Task, error) {
|
||||
getLinks, err := p.repo.GetLinks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskMap := make(map[string]shared.Task)
|
||||
|
||||
for _, item := range getLinks.Surugaya {
|
||||
if task, exists := taskMap[item.MerchUuid]; exists {
|
||||
task.OriginSurugayaLink = item.Link
|
||||
taskMap[item.MerchUuid] = task
|
||||
} else {
|
||||
taskMap[item.MerchUuid] = shared.Task{
|
||||
MerchUuid: item.MerchUuid,
|
||||
OriginSurugayaLink: item.Link,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range getLinks.Mandarake {
|
||||
if task, exists := taskMap[item.MerchUuid]; exists {
|
||||
task.OriginMandarakeLink = item.Link
|
||||
taskMap[item.MerchUuid] = task
|
||||
} else {
|
||||
taskMap[item.MerchUuid] = shared.Task{
|
||||
MerchUuid: item.MerchUuid,
|
||||
OriginMandarakeLink: item.Link,
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskMap, nil
|
||||
}
|
||||
|
||||
func (p *TaskProvider) InsertPrices([]shared.TaskResult) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *TaskRepo) GetLinks() (*Link, error) {
|
||||
var surugayaList []Surugaya
|
||||
if err := r.db.Model(&Surugaya{}).Find(&surugayaList).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mandarakeList []Mandarake
|
||||
if err := r.db.Model(&Mandarake{}).Find(&mandarakeList).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Link{
|
||||
Surugaya: surugayaList,
|
||||
Mandarake: mandarakeList,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *TaskRepo) InsertPrices() error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"database/sql"
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ type repository interface {
|
|||
getSingleMerch(userUuid, merchUuid string) (merchBundle, error)
|
||||
getAllMerch(userUuid string) ([]ListResponse, error)
|
||||
|
||||
updateMerch(payload MerchDTO, userUuid string) error
|
||||
updateMerch(payload UpdateMerchDTO, userUuid string) error
|
||||
|
||||
deleteMerch(userUuid, merchUuid string) error
|
||||
|
||||
|
|
@ -99,7 +100,7 @@ func (r *Repo) getAllMerch(userUuid string) ([]ListResponse, error) {
|
|||
return list, nil
|
||||
}
|
||||
|
||||
func (r *Repo) updateMerch(payload MerchDTO, userUuid string) error {
|
||||
func (r *Repo) updateMerch(payload UpdateMerchDTO, userUuid string) error {
|
||||
m := make(map[string]any)
|
||||
m["name"] = payload.Name
|
||||
m["updated_at"] = sql.NullTime{
|
||||
|
|
@ -115,27 +116,20 @@ func (r *Repo) updateMerch(payload MerchDTO, userUuid string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// surugaya
|
||||
fields := make(map[string]any, 2)
|
||||
if payload.OriginSurugaya.Link != "" {
|
||||
fields["link"] = payload.OriginSurugaya.Link
|
||||
}
|
||||
|
||||
if len(fields) > 0 {
|
||||
if err := r.db.
|
||||
Model(&Surugaya{}).
|
||||
Where("merch_uuid = ?", payload.MerchUuid).
|
||||
Updates(fields).Error; err != nil {
|
||||
switch payload.Origin {
|
||||
case "surugaya":
|
||||
if err := r.upsertOrigin(&Surugaya{
|
||||
MerchUuid: payload.MerchUuid,
|
||||
Link: payload.Link,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// mandarake
|
||||
if payload.OriginMandarake.Link != "" {
|
||||
if err := r.db.
|
||||
Model(&Mandarake{}).
|
||||
Where("merch_uuid = ?", payload.MerchUuid).
|
||||
Update("link", payload.OriginMandarake.Link).Error; err != nil {
|
||||
case "mandarake":
|
||||
if err := r.upsertOrigin(&Mandarake{
|
||||
MerchUuid: payload.MerchUuid,
|
||||
Link: payload.Link,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -223,3 +217,10 @@ func (r *Repo) getDistinctPrices(userUuid, merchUuid string, period time.Time) (
|
|||
}
|
||||
return prices, nil
|
||||
}
|
||||
|
||||
func (r *Repo) upsertOrigin(model any) error {
|
||||
return r.db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "merch_uuid"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"link"}),
|
||||
}).Create(model).Error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,10 +67,19 @@ func (s *service) getAllMerch(userUuid string) ([]ListResponse, error) {
|
|||
return s.repo.getAllMerch(userUuid)
|
||||
}
|
||||
|
||||
func (s *service) updateMerch(payload MerchDTO, userUuid string) error {
|
||||
func (s *service) updateMerch(payload UpdateMerchDTO, userUuid string) error {
|
||||
if payload.MerchUuid == "" {
|
||||
return errors.New("no MerchUuid or empty payload")
|
||||
return errors.New("no merch uuid provided")
|
||||
}
|
||||
|
||||
if payload.Origin == "" {
|
||||
return errors.New("no origin provided")
|
||||
}
|
||||
|
||||
if payload.Link == "" {
|
||||
return errors.New("no link provided")
|
||||
}
|
||||
|
||||
return s.repo.updateMerch(payload, userUuid)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,33 +4,46 @@ import (
|
|||
"context"
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"merch-parser-api/internal/interfaces"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
address string
|
||||
apiPrefix string
|
||||
modules []interfaces.Module
|
||||
routerHandler interfaces.Router
|
||||
router *gin.Engine
|
||||
host string
|
||||
address string
|
||||
apiPrefix string
|
||||
modules []interfaces.Module
|
||||
routerHandler interfaces.Router
|
||||
router *gin.Engine
|
||||
grpcServer *grpc.Server
|
||||
grpcServerPort string
|
||||
grpcClientPort string
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
Host string
|
||||
Port string
|
||||
ApiPrefix string
|
||||
Modules []interfaces.Module
|
||||
RouterHandler interfaces.Router
|
||||
Host string
|
||||
Port string
|
||||
ApiPrefix string
|
||||
Modules []interfaces.Module
|
||||
RouterHandler interfaces.Router
|
||||
GrpcServer *grpc.Server
|
||||
GrpcServerPort string
|
||||
GrpcClientPort string
|
||||
}
|
||||
|
||||
func NewApp(deps Deps) *App {
|
||||
app := &App{
|
||||
address: deps.Host + ":" + deps.Port,
|
||||
apiPrefix: deps.ApiPrefix,
|
||||
routerHandler: deps.RouterHandler,
|
||||
modules: deps.Modules,
|
||||
host: deps.Host,
|
||||
address: deps.Host + ":" + deps.Port,
|
||||
apiPrefix: deps.ApiPrefix,
|
||||
routerHandler: deps.RouterHandler,
|
||||
modules: deps.Modules,
|
||||
grpcServer: deps.GrpcServer,
|
||||
grpcServerPort: deps.GrpcServerPort,
|
||||
grpcClientPort: deps.GrpcClientPort,
|
||||
}
|
||||
|
||||
app.router = app.routerHandler.Set()
|
||||
|
|
@ -62,6 +75,19 @@ func (a *App) Run(ctx context.Context) error {
|
|||
serverErr <- server.ListenAndServe()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
listener, err := net.Listen("tcp", net.JoinHostPort(a.host, a.grpcServerPort))
|
||||
if err != nil {
|
||||
log.WithField("err", err).Fatal("gRPC Server | Listener")
|
||||
}
|
||||
|
||||
err = a.grpcServer.Serve(listener)
|
||||
if err != nil {
|
||||
log.WithField("err", err).Fatal("gRPC Server | Serve")
|
||||
}
|
||||
}()
|
||||
log.Info("Starting gRPC server on port: ", a.grpcServerPort)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Info("Shutting down server")
|
||||
|
|
|
|||
106
internal/grpcService/handler.go
Normal file
106
internal/grpcService/handler.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package grpcService
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"io"
|
||||
"merch-parser-api/internal/interfaces"
|
||||
"merch-parser-api/internal/shared"
|
||||
pb "merch-parser-api/proto/taskProcessor"
|
||||
"time"
|
||||
)
|
||||
|
||||
type repoServer struct {
|
||||
pb.UnimplementedTaskProcessorServer
|
||||
taskProvider interfaces.TaskProvider
|
||||
}
|
||||
|
||||
func NewGrpcServer(taskProvider interfaces.TaskProvider) *grpc.Server {
|
||||
srv := grpc.NewServer()
|
||||
repoSrv := &repoServer{
|
||||
taskProvider: taskProvider,
|
||||
}
|
||||
|
||||
pb.RegisterTaskProcessorServer(srv, repoSrv)
|
||||
return srv
|
||||
}
|
||||
|
||||
func (r *repoServer) RequestTask(_ *emptypb.Empty, stream pb.TaskProcessor_RequestTaskServer) error {
|
||||
tasks, err := r.taskProvider.PrepareTasks()
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("gRPC Server | Request task error")
|
||||
return err
|
||||
}
|
||||
|
||||
for _, task := range tasks {
|
||||
if err = stream.Send(&pb.Task{
|
||||
MerchUuid: task.MerchUuid,
|
||||
OriginSurugayaLink: task.OriginSurugayaLink,
|
||||
OriginMandarakeLink: task.OriginMandarakeLink,
|
||||
}); err != nil {
|
||||
log.WithField("err", err).Error("gRPC Server | Stream send error")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *repoServer) SendResult(stream pb.TaskProcessor_SendResultServer) error {
|
||||
saveInterval := time.Second * 2
|
||||
batch := make([]shared.TaskResult, 0)
|
||||
|
||||
ticker := time.NewTicker(saveInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-ticker.C:
|
||||
if len(batch) > 0 {
|
||||
err := r.taskProvider.InsertPrices(batch)
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("gRPC Server | Batch insert")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
response, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
log.Debug("gRPC EOF")
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("gRPC Server | Receive")
|
||||
return err
|
||||
}
|
||||
|
||||
entry := shared.TaskResult{
|
||||
MerchUuid: response.MerchUuid,
|
||||
Origin: response.OriginName,
|
||||
Price: response.Price,
|
||||
}
|
||||
|
||||
batch = append(batch, entry)
|
||||
log.WithField("response", entry).Debug("gRPC Server | Receive success")
|
||||
}
|
||||
|
||||
close(done)
|
||||
if len(batch) > 0 {
|
||||
err := r.taskProvider.InsertPrices(batch)
|
||||
if err != nil {
|
||||
log.WithField("err", err).Error("gRPC Server | Last data batch insert")
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
8
internal/interfaces/task.go
Normal file
8
internal/interfaces/task.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package interfaces
|
||||
|
||||
import "merch-parser-api/internal/shared"
|
||||
|
||||
type TaskProvider interface {
|
||||
PrepareTasks() (map[string]shared.Task, error)
|
||||
InsertPrices([]shared.TaskResult) error
|
||||
}
|
||||
|
|
@ -7,17 +7,15 @@ import (
|
|||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
"merch-parser-api/internal/interfaces"
|
||||
"merch-parser-api/internal/shared"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type router struct {
|
||||
apiPrefix string
|
||||
engine *gin.Engine
|
||||
ginMode string
|
||||
excludeRoutes map[string]shared.ExcludeRoute
|
||||
tokenProv interfaces.JWTProvider
|
||||
apiPrefix string
|
||||
engine *gin.Engine
|
||||
ginMode string
|
||||
tokenProv interfaces.JWTProvider
|
||||
}
|
||||
|
||||
type Deps struct {
|
||||
|
|
@ -28,8 +26,13 @@ type Deps struct {
|
|||
}
|
||||
|
||||
func NewRouter(deps Deps) interfaces.Router {
|
||||
engine := gin.Default()
|
||||
if deps.GinMode == "release" {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
} else {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
}
|
||||
|
||||
engine := gin.Default()
|
||||
if deps.GinMode == "release" {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
err := engine.SetTrustedProxies([]string{"172.20.0.0/16"})
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
package shared
|
||||
|
||||
type ExcludeRoute struct {
|
||||
Route string
|
||||
Method string
|
||||
}
|
||||
13
internal/shared/task.go
Normal file
13
internal/shared/task.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package shared
|
||||
|
||||
type Task struct {
|
||||
MerchUuid string
|
||||
OriginSurugayaLink string
|
||||
OriginMandarakeLink string
|
||||
}
|
||||
|
||||
type TaskResult struct {
|
||||
MerchUuid string
|
||||
Origin string
|
||||
Price uint32
|
||||
}
|
||||
41
proto/task.proto
Normal file
41
proto/task.proto
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
syntax = "proto3";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
package taskProcessor;
|
||||
option go_package = "./taskProcessor";
|
||||
|
||||
|
||||
message Task{
|
||||
string merch_uuid = 1;
|
||||
string origin_surugaya_link = 2;
|
||||
string origin_mandarake_link = 3;
|
||||
}
|
||||
|
||||
message Result{
|
||||
string merch_uuid = 1;
|
||||
string origin_name = 2;
|
||||
uint32 price = 3;
|
||||
}
|
||||
|
||||
message ProcessorStatusRequest{}
|
||||
|
||||
message ProcessorStatusResponse {
|
||||
int64 appStart = 1;
|
||||
int64 lastCheck = 2;
|
||||
int32 tasksReceived = 3;
|
||||
int32 tasksInProgress = 4;
|
||||
int32 tasksFirstTry = 5;
|
||||
int32 tasksDoneAfterRetry = 6;
|
||||
int32 tasksFailed = 7;
|
||||
string workStatus = 8;
|
||||
int32 numCPUs = 9;
|
||||
int32 checkPeriod = 10;
|
||||
int32 retriesCount = 11;
|
||||
int32 retriesMinutes = 12;
|
||||
}
|
||||
|
||||
service TaskProcessor {
|
||||
rpc RequestTask(google.protobuf.Empty) returns (stream Task);
|
||||
rpc SendResult(stream Result) returns (google.protobuf.Empty);
|
||||
rpc ProcessorStatus(ProcessorStatusRequest) returns (ProcessorStatusResponse);
|
||||
}
|
||||
409
proto/taskProcessor/task.pb.go
Normal file
409
proto/taskProcessor/task.pb.go
Normal file
|
|
@ -0,0 +1,409 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.8
|
||||
// protoc v6.32.0
|
||||
// source: task.proto
|
||||
|
||||
package taskProcessor
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MerchUuid string `protobuf:"bytes,1,opt,name=merch_uuid,json=merchUuid,proto3" json:"merch_uuid,omitempty"`
|
||||
OriginSurugayaLink string `protobuf:"bytes,2,opt,name=origin_surugaya_link,json=originSurugayaLink,proto3" json:"origin_surugaya_link,omitempty"`
|
||||
OriginMandarakeLink string `protobuf:"bytes,3,opt,name=origin_mandarake_link,json=originMandarakeLink,proto3" json:"origin_mandarake_link,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Task) Reset() {
|
||||
*x = Task{}
|
||||
mi := &file_task_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Task) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Task) ProtoMessage() {}
|
||||
|
||||
func (x *Task) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_task_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Task.ProtoReflect.Descriptor instead.
|
||||
func (*Task) Descriptor() ([]byte, []int) {
|
||||
return file_task_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Task) GetMerchUuid() string {
|
||||
if x != nil {
|
||||
return x.MerchUuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Task) GetOriginSurugayaLink() string {
|
||||
if x != nil {
|
||||
return x.OriginSurugayaLink
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Task) GetOriginMandarakeLink() string {
|
||||
if x != nil {
|
||||
return x.OriginMandarakeLink
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MerchUuid string `protobuf:"bytes,1,opt,name=merch_uuid,json=merchUuid,proto3" json:"merch_uuid,omitempty"`
|
||||
OriginName string `protobuf:"bytes,2,opt,name=origin_name,json=originName,proto3" json:"origin_name,omitempty"`
|
||||
Price uint32 `protobuf:"varint,3,opt,name=price,proto3" json:"price,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Result) Reset() {
|
||||
*x = Result{}
|
||||
mi := &file_task_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Result) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Result) ProtoMessage() {}
|
||||
|
||||
func (x *Result) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_task_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Result.ProtoReflect.Descriptor instead.
|
||||
func (*Result) Descriptor() ([]byte, []int) {
|
||||
return file_task_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Result) GetMerchUuid() string {
|
||||
if x != nil {
|
||||
return x.MerchUuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Result) GetOriginName() string {
|
||||
if x != nil {
|
||||
return x.OriginName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Result) GetPrice() uint32 {
|
||||
if x != nil {
|
||||
return x.Price
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ProcessorStatusRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusRequest) Reset() {
|
||||
*x = ProcessorStatusRequest{}
|
||||
mi := &file_task_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProcessorStatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ProcessorStatusRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_task_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProcessorStatusRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ProcessorStatusRequest) Descriptor() ([]byte, []int) {
|
||||
return file_task_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type ProcessorStatusResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AppStart int64 `protobuf:"varint,1,opt,name=appStart,proto3" json:"appStart,omitempty"`
|
||||
LastCheck int64 `protobuf:"varint,2,opt,name=lastCheck,proto3" json:"lastCheck,omitempty"`
|
||||
TasksReceived int32 `protobuf:"varint,3,opt,name=tasksReceived,proto3" json:"tasksReceived,omitempty"`
|
||||
TasksInProgress int32 `protobuf:"varint,4,opt,name=tasksInProgress,proto3" json:"tasksInProgress,omitempty"`
|
||||
TasksFirstTry int32 `protobuf:"varint,5,opt,name=tasksFirstTry,proto3" json:"tasksFirstTry,omitempty"`
|
||||
TasksDoneAfterRetry int32 `protobuf:"varint,6,opt,name=tasksDoneAfterRetry,proto3" json:"tasksDoneAfterRetry,omitempty"`
|
||||
TasksFailed int32 `protobuf:"varint,7,opt,name=tasksFailed,proto3" json:"tasksFailed,omitempty"`
|
||||
WorkStatus string `protobuf:"bytes,8,opt,name=workStatus,proto3" json:"workStatus,omitempty"`
|
||||
NumCPUs int32 `protobuf:"varint,9,opt,name=numCPUs,proto3" json:"numCPUs,omitempty"`
|
||||
CheckPeriod int32 `protobuf:"varint,10,opt,name=checkPeriod,proto3" json:"checkPeriod,omitempty"`
|
||||
RetriesCount int32 `protobuf:"varint,11,opt,name=retriesCount,proto3" json:"retriesCount,omitempty"`
|
||||
RetriesMinutes int32 `protobuf:"varint,12,opt,name=retriesMinutes,proto3" json:"retriesMinutes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) Reset() {
|
||||
*x = ProcessorStatusResponse{}
|
||||
mi := &file_task_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ProcessorStatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ProcessorStatusResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_task_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ProcessorStatusResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ProcessorStatusResponse) Descriptor() ([]byte, []int) {
|
||||
return file_task_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetAppStart() int64 {
|
||||
if x != nil {
|
||||
return x.AppStart
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetLastCheck() int64 {
|
||||
if x != nil {
|
||||
return x.LastCheck
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetTasksReceived() int32 {
|
||||
if x != nil {
|
||||
return x.TasksReceived
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetTasksInProgress() int32 {
|
||||
if x != nil {
|
||||
return x.TasksInProgress
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetTasksFirstTry() int32 {
|
||||
if x != nil {
|
||||
return x.TasksFirstTry
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetTasksDoneAfterRetry() int32 {
|
||||
if x != nil {
|
||||
return x.TasksDoneAfterRetry
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetTasksFailed() int32 {
|
||||
if x != nil {
|
||||
return x.TasksFailed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetWorkStatus() string {
|
||||
if x != nil {
|
||||
return x.WorkStatus
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetNumCPUs() int32 {
|
||||
if x != nil {
|
||||
return x.NumCPUs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetCheckPeriod() int32 {
|
||||
if x != nil {
|
||||
return x.CheckPeriod
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetRetriesCount() int32 {
|
||||
if x != nil {
|
||||
return x.RetriesCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ProcessorStatusResponse) GetRetriesMinutes() int32 {
|
||||
if x != nil {
|
||||
return x.RetriesMinutes
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_task_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_task_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"task.proto\x12\rtaskProcessor\x1a\x1bgoogle/protobuf/empty.proto\"\x8b\x01\n" +
|
||||
"\x04Task\x12\x1d\n" +
|
||||
"\n" +
|
||||
"merch_uuid\x18\x01 \x01(\tR\tmerchUuid\x120\n" +
|
||||
"\x14origin_surugaya_link\x18\x02 \x01(\tR\x12originSurugayaLink\x122\n" +
|
||||
"\x15origin_mandarake_link\x18\x03 \x01(\tR\x13originMandarakeLink\"^\n" +
|
||||
"\x06Result\x12\x1d\n" +
|
||||
"\n" +
|
||||
"merch_uuid\x18\x01 \x01(\tR\tmerchUuid\x12\x1f\n" +
|
||||
"\vorigin_name\x18\x02 \x01(\tR\n" +
|
||||
"originName\x12\x14\n" +
|
||||
"\x05price\x18\x03 \x01(\rR\x05price\"\x18\n" +
|
||||
"\x16ProcessorStatusRequest\"\xc5\x03\n" +
|
||||
"\x17ProcessorStatusResponse\x12\x1a\n" +
|
||||
"\bappStart\x18\x01 \x01(\x03R\bappStart\x12\x1c\n" +
|
||||
"\tlastCheck\x18\x02 \x01(\x03R\tlastCheck\x12$\n" +
|
||||
"\rtasksReceived\x18\x03 \x01(\x05R\rtasksReceived\x12(\n" +
|
||||
"\x0ftasksInProgress\x18\x04 \x01(\x05R\x0ftasksInProgress\x12$\n" +
|
||||
"\rtasksFirstTry\x18\x05 \x01(\x05R\rtasksFirstTry\x120\n" +
|
||||
"\x13tasksDoneAfterRetry\x18\x06 \x01(\x05R\x13tasksDoneAfterRetry\x12 \n" +
|
||||
"\vtasksFailed\x18\a \x01(\x05R\vtasksFailed\x12\x1e\n" +
|
||||
"\n" +
|
||||
"workStatus\x18\b \x01(\tR\n" +
|
||||
"workStatus\x12\x18\n" +
|
||||
"\anumCPUs\x18\t \x01(\x05R\anumCPUs\x12 \n" +
|
||||
"\vcheckPeriod\x18\n" +
|
||||
" \x01(\x05R\vcheckPeriod\x12\"\n" +
|
||||
"\fretriesCount\x18\v \x01(\x05R\fretriesCount\x12&\n" +
|
||||
"\x0eretriesMinutes\x18\f \x01(\x05R\x0eretriesMinutes2\xee\x01\n" +
|
||||
"\rTaskProcessor\x12<\n" +
|
||||
"\vRequestTask\x12\x16.google.protobuf.Empty\x1a\x13.taskProcessor.Task0\x01\x12=\n" +
|
||||
"\n" +
|
||||
"SendResult\x12\x15.taskProcessor.Result\x1a\x16.google.protobuf.Empty(\x01\x12`\n" +
|
||||
"\x0fProcessorStatus\x12%.taskProcessor.ProcessorStatusRequest\x1a&.taskProcessor.ProcessorStatusResponseB\x11Z\x0f./taskProcessorb\x06proto3"
|
||||
|
||||
var (
|
||||
file_task_proto_rawDescOnce sync.Once
|
||||
file_task_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_task_proto_rawDescGZIP() []byte {
|
||||
file_task_proto_rawDescOnce.Do(func() {
|
||||
file_task_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_task_proto_rawDesc), len(file_task_proto_rawDesc)))
|
||||
})
|
||||
return file_task_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_task_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_task_proto_goTypes = []any{
|
||||
(*Task)(nil), // 0: taskProcessor.Task
|
||||
(*Result)(nil), // 1: taskProcessor.Result
|
||||
(*ProcessorStatusRequest)(nil), // 2: taskProcessor.ProcessorStatusRequest
|
||||
(*ProcessorStatusResponse)(nil), // 3: taskProcessor.ProcessorStatusResponse
|
||||
(*emptypb.Empty)(nil), // 4: google.protobuf.Empty
|
||||
}
|
||||
var file_task_proto_depIdxs = []int32{
|
||||
4, // 0: taskProcessor.TaskProcessor.RequestTask:input_type -> google.protobuf.Empty
|
||||
1, // 1: taskProcessor.TaskProcessor.SendResult:input_type -> taskProcessor.Result
|
||||
2, // 2: taskProcessor.TaskProcessor.ProcessorStatus:input_type -> taskProcessor.ProcessorStatusRequest
|
||||
0, // 3: taskProcessor.TaskProcessor.RequestTask:output_type -> taskProcessor.Task
|
||||
4, // 4: taskProcessor.TaskProcessor.SendResult:output_type -> google.protobuf.Empty
|
||||
3, // 5: taskProcessor.TaskProcessor.ProcessorStatus:output_type -> taskProcessor.ProcessorStatusResponse
|
||||
3, // [3:6] is the sub-list for method output_type
|
||||
0, // [0:3] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_task_proto_init() }
|
||||
func file_task_proto_init() {
|
||||
if File_task_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_task_proto_rawDesc), len(file_task_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_task_proto_goTypes,
|
||||
DependencyIndexes: file_task_proto_depIdxs,
|
||||
MessageInfos: file_task_proto_msgTypes,
|
||||
}.Build()
|
||||
File_task_proto = out.File
|
||||
file_task_proto_goTypes = nil
|
||||
file_task_proto_depIdxs = nil
|
||||
}
|
||||
195
proto/taskProcessor/task_grpc.pb.go
Normal file
195
proto/taskProcessor/task_grpc.pb.go
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v6.32.0
|
||||
// source: task.proto
|
||||
|
||||
package taskProcessor
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
TaskProcessor_RequestTask_FullMethodName = "/taskProcessor.TaskProcessor/RequestTask"
|
||||
TaskProcessor_SendResult_FullMethodName = "/taskProcessor.TaskProcessor/SendResult"
|
||||
TaskProcessor_ProcessorStatus_FullMethodName = "/taskProcessor.TaskProcessor/ProcessorStatus"
|
||||
)
|
||||
|
||||
// TaskProcessorClient is the client API for TaskProcessor service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type TaskProcessorClient interface {
|
||||
RequestTask(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Task], error)
|
||||
SendResult(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[Result, emptypb.Empty], error)
|
||||
ProcessorStatus(ctx context.Context, in *ProcessorStatusRequest, opts ...grpc.CallOption) (*ProcessorStatusResponse, error)
|
||||
}
|
||||
|
||||
type taskProcessorClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewTaskProcessorClient(cc grpc.ClientConnInterface) TaskProcessorClient {
|
||||
return &taskProcessorClient{cc}
|
||||
}
|
||||
|
||||
func (c *taskProcessorClient) RequestTask(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Task], error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &TaskProcessor_ServiceDesc.Streams[0], TaskProcessor_RequestTask_FullMethodName, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &grpc.GenericClientStream[emptypb.Empty, Task]{ClientStream: stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type TaskProcessor_RequestTaskClient = grpc.ServerStreamingClient[Task]
|
||||
|
||||
func (c *taskProcessorClient) SendResult(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[Result, emptypb.Empty], error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &TaskProcessor_ServiceDesc.Streams[1], TaskProcessor_SendResult_FullMethodName, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := &grpc.GenericClientStream[Result, emptypb.Empty]{ClientStream: stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type TaskProcessor_SendResultClient = grpc.ClientStreamingClient[Result, emptypb.Empty]
|
||||
|
||||
func (c *taskProcessorClient) ProcessorStatus(ctx context.Context, in *ProcessorStatusRequest, opts ...grpc.CallOption) (*ProcessorStatusResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ProcessorStatusResponse)
|
||||
err := c.cc.Invoke(ctx, TaskProcessor_ProcessorStatus_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TaskProcessorServer is the server API for TaskProcessor service.
|
||||
// All implementations must embed UnimplementedTaskProcessorServer
|
||||
// for forward compatibility.
|
||||
type TaskProcessorServer interface {
|
||||
RequestTask(*emptypb.Empty, grpc.ServerStreamingServer[Task]) error
|
||||
SendResult(grpc.ClientStreamingServer[Result, emptypb.Empty]) error
|
||||
ProcessorStatus(context.Context, *ProcessorStatusRequest) (*ProcessorStatusResponse, error)
|
||||
mustEmbedUnimplementedTaskProcessorServer()
|
||||
}
|
||||
|
||||
// UnimplementedTaskProcessorServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedTaskProcessorServer struct{}
|
||||
|
||||
func (UnimplementedTaskProcessorServer) RequestTask(*emptypb.Empty, grpc.ServerStreamingServer[Task]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method RequestTask not implemented")
|
||||
}
|
||||
func (UnimplementedTaskProcessorServer) SendResult(grpc.ClientStreamingServer[Result, emptypb.Empty]) error {
|
||||
return status.Errorf(codes.Unimplemented, "method SendResult not implemented")
|
||||
}
|
||||
func (UnimplementedTaskProcessorServer) ProcessorStatus(context.Context, *ProcessorStatusRequest) (*ProcessorStatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ProcessorStatus not implemented")
|
||||
}
|
||||
func (UnimplementedTaskProcessorServer) mustEmbedUnimplementedTaskProcessorServer() {}
|
||||
func (UnimplementedTaskProcessorServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeTaskProcessorServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to TaskProcessorServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeTaskProcessorServer interface {
|
||||
mustEmbedUnimplementedTaskProcessorServer()
|
||||
}
|
||||
|
||||
func RegisterTaskProcessorServer(s grpc.ServiceRegistrar, srv TaskProcessorServer) {
|
||||
// If the following call pancis, it indicates UnimplementedTaskProcessorServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&TaskProcessor_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _TaskProcessor_RequestTask_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(emptypb.Empty)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(TaskProcessorServer).RequestTask(m, &grpc.GenericServerStream[emptypb.Empty, Task]{ServerStream: stream})
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type TaskProcessor_RequestTaskServer = grpc.ServerStreamingServer[Task]
|
||||
|
||||
func _TaskProcessor_SendResult_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(TaskProcessorServer).SendResult(&grpc.GenericServerStream[Result, emptypb.Empty]{ServerStream: stream})
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type TaskProcessor_SendResultServer = grpc.ClientStreamingServer[Result, emptypb.Empty]
|
||||
|
||||
func _TaskProcessor_ProcessorStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ProcessorStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TaskProcessorServer).ProcessorStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: TaskProcessor_ProcessorStatus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TaskProcessorServer).ProcessorStatus(ctx, req.(*ProcessorStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// TaskProcessor_ServiceDesc is the grpc.ServiceDesc for TaskProcessor service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var TaskProcessor_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "taskProcessor.TaskProcessor",
|
||||
HandlerType: (*TaskProcessorServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ProcessorStatus",
|
||||
Handler: _TaskProcessor_ProcessorStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "RequestTask",
|
||||
Handler: _TaskProcessor_RequestTask_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
{
|
||||
StreamName: "SendResult",
|
||||
Handler: _TaskProcessor_SendResult_Handler,
|
||||
ClientStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "task.proto",
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue