diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..5518484 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,140 @@ +run: + timeout: 3m + # Exit code when at least one issue was found. + # Default: 1 + issues-exit-code: 2 + # Include test files or not. + # Default: true + tests: false + +# Reference URL: https://golangci-lint.run/usage/linters/ +linters: + # Disable everything by default so upgrades to not include new - default + # enabled- linters. + disable-all: true + # Specifically enable linters we want to use. + enable: + # - depguard + - errcheck + # - godot + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - revive + # - staticcheck + - typecheck + - unused + # - wsl + - asasalint + - asciicheck + - bidichk + - bodyclose + # - containedctx + - contextcheck + # - cyclop + # - varnamelen + # - gci + - wastedassign + - whitespace + # - wrapcheck + - thelper + - tparallel + - unconvert + - unparam + - usestdlibvars + - tenv + - testableexamples + - stylecheck + - sqlclosecheck + - nosprintfhostport + - paralleltest + - prealloc + - predeclared + - promlinter + - reassign + - rowserrcheck + - nakedret + - nestif + - nilerr + - nilnil + - nlreturn + - noctx + - nolintlint + - nonamedreturns + - decorder + - dogsled + # - dupl + - dupword + - durationcheck + - errchkjson + - errname + - errorlint + # - execinquery + - exhaustive + - exportloopref + - forbidigo + - forcetypeassert + # - gochecknoglobals + - gochecknoinits + - gocognit + - goconst + - gocritic + - gocyclo + # - godox + # - goerr113 + # - gofumpt + - goheader + - gomoddirectives + # - gomodguard always failed + - goprintffuncname + - gosec + - grouper + - importas + - interfacebloat + # - ireturn + - lll + - loggercheck + - maintidx + - makezero + +issues: + exclude-rules: + - path: _test\.go + linters: + - funlen + - goconst + - interfacer + - dupl + - lll + - goerr113 + - errcheck + - gocritic + - cyclop + - wrapcheck + - gocognit + - contextcheck + +linters-settings: + gci: + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + gocognit: + # Minimal code complexity to report. + # Default: 30 (but we recommend 10-20) + min-complexity: 40 + nestif: + # Minimal complexity of if statements to report. + # Default: 5 + min-complexity: 10 + lll: + # Max line length, lines longer will be reported. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option. + # Default: 120. + line-length: 200 + # Tab width in spaces. + # Default: 1 + tab-width: 1 diff --git a/etc/service.yaml b/etc/service.yaml index f9a189a..319ba6f 100644 --- a/etc/service.yaml +++ b/etc/service.yaml @@ -4,3 +4,13 @@ Etcd: Hosts: - 127.0.0.1:2379 Key: service.rpc +SMTP: + Host: smtp.mailgun.org + Port: 25 + User: postmaster@code.30cm.net + Password: 9015592e10f385e4f16705e00a5e0d3d-2b91eb47-31205b4e + +SMSSender: + User: daniel@30cm.net + Password : test123 + diff --git a/go.mod b/go.mod index eee482d..f983540 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.3 require ( code.30cm.net/digimon/library-go/errors v1.0.0 code.30cm.net/digimon/library-go/validator v1.0.0 + code.30cm.net/digimon/library-go/worker_pool v0.0.0-20240820153352-f9c90a90f5e2 github.com/minchao/go-mitake v1.0.0 github.com/zeromicro/go-zero v1.7.0 google.golang.org/grpc v1.65.0 @@ -49,6 +50,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect + github.com/panjf2000/ants/v2 v2.10.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.5.0 // indirect @@ -77,6 +79,7 @@ require ( golang.org/x/crypto v0.25.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/term v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect diff --git a/internal/logic/senderservice/send_mail_by_template_id_logic.go b/internal/logic/senderservice/send_mail_by_template_id_logic.go index abf4b49..b9decc9 100644 --- a/internal/logic/senderservice/send_mail_by_template_id_logic.go +++ b/internal/logic/senderservice/send_mail_by_template_id_logic.go @@ -3,9 +3,10 @@ package senderservicelogic import ( "app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/internal/svc" - ers "code.30cm.net/digimon/library-go/errors" "context" "fmt" + + ers "code.30cm.net/digimon/library-go/errors" "github.com/zeromicro/go-zero/core/logx" ) diff --git a/internal/logic/senderservice/send_mail_logic.go b/internal/logic/senderservice/send_mail_logic.go index 39ad124..c7aa930 100644 --- a/internal/logic/senderservice/send_mail_logic.go +++ b/internal/logic/senderservice/send_mail_logic.go @@ -2,9 +2,10 @@ package senderservicelogic import ( "app-cloudep-notification-service/internal/domain/usecase" - ers "code.30cm.net/digimon/library-go/errors" "context" + ers "code.30cm.net/digimon/library-go/errors" + "app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/internal/svc" @@ -47,6 +48,7 @@ func (l *SendMailLogic) SendMail(in *notification.SendMailReq) (*notification.OK return nil, ers.InvalidFormat(err.Error()) } + // TODO 以後可以做換線 err := l.svcCtx.MailSender.SendMail(l.ctx, usecase.MailReq{ To: in.GetTo(), Subject: in.GetSubject(), diff --git a/internal/logic/senderservice/send_sms_logic.go b/internal/logic/senderservice/send_sms_logic.go index 152d890..83d79fa 100644 --- a/internal/logic/senderservice/send_sms_logic.go +++ b/internal/logic/senderservice/send_sms_logic.go @@ -2,9 +2,10 @@ package senderservicelogic import ( "app-cloudep-notification-service/internal/domain/usecase" - ers "code.30cm.net/digimon/library-go/errors" "context" + ers "code.30cm.net/digimon/library-go/errors" + "app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/internal/svc" @@ -44,6 +45,7 @@ func (l *SendSmsLogic) SendSms(in *notification.SendSMSReq) (*notification.OKRes return nil, ers.InvalidFormat(err.Error()) } + // TODO 以後可以做換線 err := l.svcCtx.SMSSender.SendSMS(l.ctx, usecase.SMSReq{ RecipientAddress: in.GetTo(), RecipientName: in.GetRecipientName(), diff --git a/internal/server/senderservice/sender_service_server.go b/internal/server/senderservice/sender_service_server.go index 7300421..99f6d32 100644 --- a/internal/server/senderservice/sender_service_server.go +++ b/internal/server/senderservice/sender_service_server.go @@ -7,7 +7,7 @@ import ( "context" "app-cloudep-notification-service/gen_result/pb/notification" - "app-cloudep-notification-service/internal/logic/senderservice" + senderservicelogic "app-cloudep-notification-service/internal/logic/senderservice" "app-cloudep-notification-service/internal/svc" ) diff --git a/internal/svc/service_context.go b/internal/svc/service_context.go index 09a29c1..7ce53b9 100644 --- a/internal/svc/service_context.go +++ b/internal/svc/service_context.go @@ -4,6 +4,7 @@ import ( "app-cloudep-notification-service/internal/config" domainUC "app-cloudep-notification-service/internal/domain/usecase" "app-cloudep-notification-service/internal/usecase" + v "code.30cm.net/digimon/library-go/validator" ) diff --git a/internal/usecase/mitake.go b/internal/usecase/mitake.go index cd8e622..ac332bc 100644 --- a/internal/usecase/mitake.go +++ b/internal/usecase/mitake.go @@ -4,6 +4,7 @@ import ( "app-cloudep-notification-service/internal/config" "app-cloudep-notification-service/internal/domain/usecase" "context" + "github.com/minchao/go-mitake" ) diff --git a/internal/usecase/smtp.go b/internal/usecase/smtp.go index 9a10771..f4d97e7 100644 --- a/internal/usecase/smtp.go +++ b/internal/usecase/smtp.go @@ -3,7 +3,12 @@ package usecase import ( "app-cloudep-notification-service/internal/config" "app-cloudep-notification-service/internal/domain/usecase" + + pool "code.30cm.net/digimon/library-go/worker_pool" + "github.com/zeromicro/go-zero/core/logx" + "context" + "gopkg.in/gomail.v2" ) @@ -16,19 +21,28 @@ type MailUseCase struct { Port int User string Password string + Pool pool.WorkerPool } func (mu *MailUseCase) SendMail(_ context.Context, req usecase.MailReq) error { - m := gomail.NewMessage() - m.SetHeader("From", req.From) - m.SetHeader("To", req.To) - m.SetHeader("Subject", req.Subject) - m.SetBody("text/html", req.Body) - d := gomail.NewDialer(mu.Host, mu.Port, mu.User, mu.Password) - if err := d.DialAndSend(m); err != nil { - return err - } - return nil + // 用 goroutine pool 送,否則會超時 + err := mu.Pool.Submit(func() { + m := gomail.NewMessage() + m.SetHeader("From", req.From) + m.SetHeader("To", req.To) + m.SetHeader("Subject", req.Subject) + m.SetBody("text/html", req.Body) + d := gomail.NewDialer(mu.Host, mu.Port, mu.User, mu.Password) + if err := d.DialAndSend(m); err != nil { + logx.WithCallerSkip(1).WithFields( + logx.Field("func", "MailUseCase.SendMail"), + logx.Field("req", req), + logx.Field("err", err), + ).Error("failed to send mail by mailgun") + } + }) + + return err } func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase { @@ -37,5 +51,6 @@ func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase { Port: param.Conf.SMTP.Port, User: param.Conf.SMTP.User, Password: param.Conf.SMTP.Password, + Pool: pool.NewWorkerPool(2000), } }