Passed
Push — master ( 4e9e72...8e2c0a )
by Tolga
03:36 queued 16s
created

  A

Complexity

Conditions 5

Size

Total Lines 21
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 17
nop 2
dl 0
loc 21
rs 9.0833
c 0
b 0
f 0
1
package decorators
2
3
import (
4
	"context"
5
	"errors"
6
7
	"github.com/afex/hystrix-go/hystrix"
8
9
	"github.com/Permify/permify/internal/storage"
10
	base "github.com/Permify/permify/pkg/pb/base/v1"
11
)
12
13
// TenantWriterWithCircuitBreaker - Add circuit breaker behaviour to tenant writer
14
type TenantWriterWithCircuitBreaker struct {
15
	delegate storage.TenantWriter
16
	timeout  int
17
}
18
19
// NewTenantWriterWithCircuitBreaker - Add circuit breaker behaviour to new bundle reader
20
func NewTenantWriterWithCircuitBreaker(delegate storage.TenantWriter, timeout int) *TenantWriterWithCircuitBreaker {
21
	return &TenantWriterWithCircuitBreaker{delegate: delegate, timeout: timeout}
22
}
23
24
// CreateTenant - Create tenant from the repository
25
func (r *TenantWriterWithCircuitBreaker) CreateTenant(ctx context.Context, id, name string) (result *base.Tenant, err error) {
26
	type circuitBreakerResponse struct {
27
		Tenant *base.Tenant
28
		Error  error
29
	}
30
31
	output := make(chan circuitBreakerResponse, 1)
32
	hystrix.ConfigureCommand("tenantWriter.createTenant", hystrix.CommandConfig{Timeout: r.timeout})
33
	bErrors := hystrix.Go("tenantWriter.createTenant", func() error {
34
		tenant, err := r.delegate.CreateTenant(ctx, id, name)
35
		output <- circuitBreakerResponse{Tenant: tenant, Error: err}
36
		return nil
37
	}, func(err error) error {
38
		return nil
39
	})
40
41
	select {
42
	case out := <-output:
43
		return out.Tenant, out.Error
44
	case <-bErrors:
45
		return nil, errors.New(base.ErrorCode_ERROR_CODE_CIRCUIT_BREAKER.String())
46
	}
47
}
48
49
// DeleteTenant - Delete tenant from the repository
50
func (r *TenantWriterWithCircuitBreaker) DeleteTenant(ctx context.Context, tenantID string) (result *base.Tenant, err error) {
51
	type circuitBreakerResponse struct {
52
		Tenant *base.Tenant
53
		Error  error
54
	}
55
56
	output := make(chan circuitBreakerResponse, 1)
57
	hystrix.ConfigureCommand("tenantWriter.deleteTenant", hystrix.CommandConfig{Timeout: r.timeout})
58
	bErrors := hystrix.Go("tenantWriter.deleteTenant", func() error {
59
		tenant, err := r.delegate.DeleteTenant(ctx, tenantID)
60
		output <- circuitBreakerResponse{Tenant: tenant, Error: err}
61
		return nil
62
	}, func(err error) error {
63
		return nil
64
	})
65
66
	select {
67
	case out := <-output:
68
		return out.Tenant, out.Error
69
	case <-bErrors:
70
		return nil, errors.New(base.ErrorCode_ERROR_CODE_CIRCUIT_BREAKER.String())
71
	}
72
}
73