mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 21:49:52 +00:00
Merge branch 'next' into feat/new-workflow
This commit is contained in:
commit
ee2cca17fe
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-acme/lego/v4/lego"
|
"github.com/go-acme/lego/v4/lego"
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
|
"golang.org/x/sync/singleflight"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/domain"
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
"github.com/usual2970/certimate/internal/pkg/utils/certs"
|
"github.com/usual2970/certimate/internal/pkg/utils/certs"
|
||||||
@ -79,9 +80,21 @@ type acmeAccountRepository interface {
|
|||||||
Save(ca, email, key string, resource *registration.Resource) error
|
Save(ca, email, key string, resource *registration.Resource) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerAcmeUser(client *lego.Client, sslProviderConfig *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) {
|
var registerGroup singleflight.Group
|
||||||
// TODO: fix 潜在的并发问题
|
|
||||||
|
|
||||||
|
func registerAcmeUser(client *lego.Client, sslProviderConfig *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) {
|
||||||
|
resp, err, _ := registerGroup.Do(fmt.Sprintf("register_acme_user_%s_%s", sslProviderConfig.Provider, user.GetEmail()), func() (interface{}, error) {
|
||||||
|
return register(client, sslProviderConfig, user)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.(*registration.Resource), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func register(client *lego.Client, sslProviderConfig *acmeSSLProviderConfig, user *acmeUser) (*registration.Resource, error) {
|
||||||
var reg *registration.Resource
|
var reg *registration.Resource
|
||||||
var err error
|
var err error
|
||||||
switch sslProviderConfig.Provider {
|
switch sslProviderConfig.Provider {
|
||||||
|
@ -7,12 +7,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
"github.com/go-acme/lego/v4/certificate"
|
"github.com/go-acme/lego/v4/certificate"
|
||||||
"github.com/go-acme/lego/v4/challenge"
|
"github.com/go-acme/lego/v4/challenge"
|
||||||
"github.com/go-acme/lego/v4/challenge/dns01"
|
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||||
"github.com/go-acme/lego/v4/lego"
|
"github.com/go-acme/lego/v4/lego"
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/domain"
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
"github.com/usual2970/certimate/internal/pkg/utils/slices"
|
"github.com/usual2970/certimate/internal/pkg/utils/slices"
|
||||||
@ -184,6 +186,20 @@ type proxyApplicant struct {
|
|||||||
options *applicantOptions
|
options *applicantOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var limiters sync.Map
|
||||||
|
|
||||||
|
const (
|
||||||
|
limitBurst = 300
|
||||||
|
limitRate float64 = float64(1) / float64(36)
|
||||||
|
)
|
||||||
|
|
||||||
|
func getLimiter(key string) *rate.Limiter {
|
||||||
|
limiter, _ := limiters.LoadOrStore(key, rate.NewLimiter(rate.Limit(limitRate), 300))
|
||||||
|
return limiter.(*rate.Limiter)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *proxyApplicant) Apply() (*ApplyCertResult, error) {
|
func (d *proxyApplicant) Apply() (*ApplyCertResult, error) {
|
||||||
|
limiter := getLimiter(fmt.Sprintf("apply_%s", d.options.ContactEmail))
|
||||||
|
limiter.Wait(context.Background())
|
||||||
return apply(d.applicant, d.options)
|
return apply(d.applicant, d.options)
|
||||||
}
|
}
|
||||||
|
44
internal/applicant/applicant_test.go
Normal file
44
internal/applicant/applicant_test.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package applicant
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRateLimit(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
burst int
|
||||||
|
rate rate.Limit
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test1",
|
||||||
|
burst: 300,
|
||||||
|
rate: rate.Limit(float64(1) / float64(20)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
rl := rate.NewLimiter(tt.rate, tt.burst)
|
||||||
|
if rl.Burst() != tt.burst {
|
||||||
|
t.Errorf("Burst() = %v, want %v", rl.Burst(), tt.burst)
|
||||||
|
}
|
||||||
|
if rl.Limit() != tt.rate {
|
||||||
|
t.Errorf("Limit() = %v, want %v", rl.Limit(), tt.rate)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("consume all tokens at once", rl.AllowN(time.Now(), tt.burst))
|
||||||
|
|
||||||
|
t.Log("consume more", rl.Allow())
|
||||||
|
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
t.Log("consume after 5 seconds", rl.Allow())
|
||||||
|
|
||||||
|
time.Sleep(time.Second * 20)
|
||||||
|
t.Log("consume after 20 seconds", rl.Allow())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
export const version = "v0.3.0-alpha.8";
|
export const version = "v0.3.0-alpha.9";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user