125 lines
3.4 KiB
Go
125 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"tailly_clips/internal/ffmpeg"
|
|
"tailly_clips/internal/handler"
|
|
"tailly_clips/internal/moderation"
|
|
"tailly_clips/internal/repository"
|
|
"tailly_clips/internal/service"
|
|
"tailly_clips/internal/storage"
|
|
"tailly_clips/proto"
|
|
"time"
|
|
|
|
"github.com/caarlos0/env/v8"
|
|
"github.com/joho/godotenv"
|
|
_ "github.com/lib/pq"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// Config структура конфигурации
|
|
type Config struct {
|
|
DBHost string `env:"DB_HOST" env-default:"localhost"`
|
|
DBPort string `env:"DB_PORT" env-default:"5432"`
|
|
DBUser string `env:"DB_USER" env-default:"postgres"`
|
|
DBPassword string `env:"DB_PASSWORD" env-default:"postgres"`
|
|
DBName string `env:"DB_NAME" env-default:"clip_service"`
|
|
|
|
S3Endpoint string `env:"S3_ENDPOINT,required"`
|
|
S3Bucket string `env:"S3_BUCKET,required"`
|
|
S3Region string `env:"S3_REGION,required"`
|
|
S3AccessKey string `env:"S3_ACCESS_KEY,required"`
|
|
S3SecretKey string `env:"S3_SECRET_KEY,required"`
|
|
|
|
ModerationAddr string `env:"MODERATION_ADDR" env-default:"localhost:50051"`
|
|
}
|
|
|
|
func main() {
|
|
// Загрузка конфигурации
|
|
cfg, err := loadConfig()
|
|
if err != nil {
|
|
log.Fatalf("Failed to load config: %v", err)
|
|
}
|
|
|
|
// Инициализация базы данных
|
|
db, err := initDatabase(cfg)
|
|
if err != nil {
|
|
log.Fatalf("Failed to initialize database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Инициализация S3 storage
|
|
s3Storage := storage.NewS3Storage(storage.S3Config{
|
|
Endpoint: cfg.S3Endpoint,
|
|
Bucket: cfg.S3Bucket,
|
|
Region: cfg.S3Region,
|
|
AccessKey: cfg.S3AccessKey,
|
|
SecretKey: cfg.S3SecretKey,
|
|
})
|
|
|
|
modClient, err := moderation.NewModerationClient(cfg.ModerationAddr)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create moderation client: %v", err)
|
|
}
|
|
defer modClient.Close()
|
|
|
|
videoProcessor := ffmpeg.NewVideoProcessor()
|
|
clipRepo := repository.NewClipRepository(db)
|
|
likeRepo := repository.NewLikeRepository(db)
|
|
commentRepo := repository.NewCommentRepository(db)
|
|
|
|
clipService := service.NewClipService(clipRepo, s3Storage, videoProcessor, modClient)
|
|
likeService := service.NewLikeService(likeRepo, clipRepo)
|
|
commentService := service.NewCommentService(commentRepo, clipRepo)
|
|
|
|
grpcHandler := handler.NewGRPCHandler(clipService, likeService, commentService)
|
|
|
|
server := grpc.NewServer()
|
|
proto.RegisterClipServiceServer(server, grpcHandler)
|
|
|
|
lis, err := net.Listen("tcp", ":50054")
|
|
if err != nil {
|
|
log.Fatalf("Failed to listen: %v", err)
|
|
}
|
|
|
|
log.Println("Clip service started on :50054")
|
|
if err := server.Serve(lis); err != nil {
|
|
log.Fatalf("Failed to serve: %v", err)
|
|
}
|
|
}
|
|
|
|
func loadConfig() (*Config, error) {
|
|
// Загружаем .env файл (игнорируем ошибку если файла нет)
|
|
_ = godotenv.Load()
|
|
|
|
cfg := &Config{}
|
|
if err := env.Parse(cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func initDatabase(cfg *Config) (*sql.DB, error) {
|
|
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
|
|
cfg.DBHost, cfg.DBPort, cfg.DBUser, cfg.DBPassword, cfg.DBName)
|
|
|
|
db, err := sql.Open("postgres", connStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to open database: %w", err)
|
|
}
|
|
|
|
if err = db.Ping(); err != nil {
|
|
return nil, fmt.Errorf("failed to ping database: %w", err)
|
|
}
|
|
|
|
db.SetMaxOpenConns(25)
|
|
db.SetMaxIdleConns(25)
|
|
db.SetConnMaxLifetime(5 * time.Minute)
|
|
|
|
log.Println("Database connected successfully")
|
|
return db, nil
|
|
}
|