-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
43 changed files
with
758 additions
and
335 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
proxy/integration-tests/features/flows_shared_state.feature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
@secondaryTests | ||
Feature: Lunar Proxy - rate limit | ||
Background: Starts the Proxy | ||
Given API Provider is up | ||
And Lunar Proxy env var `LUNAR_STREAMS_ENABLED` set to `true` | ||
And Lunar Proxy env var `REDIS_URL` set to `redis://lunar-redis:6379` | ||
And First Shared Lunar Proxy is up | ||
And Second Shared Lunar Proxy is up | ||
|
||
@flakey | ||
Scenario: When basic rate limit flow is loaded and 2 proxies are used, they should share state | ||
Given Redis is up | ||
|
||
When Basic rate limit flow created for httpbinmock/* with 10 requests per 1 seconds | ||
And flow file is saved on lunar-proxy-pro-1 | ||
And flow file is saved on lunar-proxy-pro-2 | ||
And resource file is saved on lunar-proxy-pro-1 | ||
And resource file is saved on lunar-proxy-pro-2 | ||
|
||
And load_flows command is run on lunar-proxy-pro-1 | ||
And load_flows command is run on lunar-proxy-pro-2 | ||
|
||
And next epoch-based 1 seconds window arrives | ||
|
||
And 8 requests are sent in parallel to httpbinmock /headers through first Shared Lunar Proxy | ||
Then 8 requests returning with status 200 and 0 with 429 | ||
|
||
# Second proxy runs in shares memory state and its state at this stage is 8 | ||
When 3 requests are sent to httpbinmock /headers through second Shared Lunar Proxy | ||
# 10 with 200 and 1 with 429 since second proxy started from 8 | ||
Then 10 requests returning with status 200 and 1 with 429 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
proxy/src/libs/toolkit-core/context-manager/context_manager.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package contextmanager | ||
|
||
import ( | ||
"context" | ||
"lunar/toolkit-core/clock" | ||
"sync" | ||
|
||
"github.com/rs/zerolog/log" | ||
) | ||
|
||
// Manager is the singleton that holds the context and clock | ||
type ContextManager struct { | ||
ctx context.Context | ||
clock clock.Clock | ||
} | ||
|
||
var ( | ||
instance *ContextManager | ||
once sync.Once | ||
) | ||
|
||
// Get returns the singleton instance of ContextManager | ||
func Get() *ContextManager { | ||
if instance == nil { | ||
initContextManager(context.Background(), clock.NewRealClock()) | ||
} | ||
return instance | ||
} | ||
|
||
// WithContext returns a new instance of ContextManager with the provided context | ||
func (m *ContextManager) WithContext(ctx context.Context) *ContextManager { | ||
m.ctx = ctx | ||
return instance | ||
} | ||
|
||
// WithClock returns a new instance of ContextManager with the provided clock | ||
func (m *ContextManager) SetRealClock() *ContextManager { | ||
m.clock = clock.NewRealClock() | ||
return instance | ||
} | ||
|
||
// SetMockClock returns a new instance of ContextManager with a mock clock | ||
func (m *ContextManager) SetMockClock() *ContextManager { | ||
m.clock = clock.NewMockClock() | ||
return instance | ||
} | ||
|
||
// GetContext returns the context held by the Manager | ||
func (m *ContextManager) GetContext() context.Context { | ||
return m.ctx | ||
} | ||
|
||
// GetClock returns the current time held by the Manager | ||
func (m *ContextManager) GetClock() clock.Clock { | ||
return m.clock | ||
} | ||
|
||
// GetMockClock returns the mock time held by the Manager | ||
func (m *ContextManager) GetMockClock() *clock.MockClock { | ||
mock, ok := m.clock.(*clock.MockClock) | ||
if !ok { | ||
log.Error().Msg("Clock is not a mock clock") | ||
return nil | ||
} | ||
return mock | ||
} | ||
|
||
// initContextManager initializes the singleton instance of ContextManager | ||
func initContextManager(ctx context.Context, clk clock.Clock) { | ||
once.Do(func() { | ||
instance = &ContextManager{ | ||
ctx: ctx, | ||
clock: clk, | ||
} | ||
}) | ||
} |
56 changes: 56 additions & 0 deletions
56
proxy/src/libs/toolkit-core/context-manager/context_manager_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package contextmanager | ||
|
||
import ( | ||
"context" | ||
"lunar/toolkit-core/clock" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestInitContextManager(t *testing.T) { | ||
ctx := context.Background() | ||
clk := clock.NewRealClock() | ||
|
||
initContextManager(ctx, clk) | ||
|
||
require.NotNil(t, instance) | ||
require.Equal(t, ctx, instance.ctx) | ||
require.Equal(t, clk, instance.clock) | ||
} | ||
|
||
func TestGetContextManager(t *testing.T) { | ||
result := Get() | ||
require.NotNil(t, result) | ||
require.Equal(t, instance, result) | ||
} | ||
|
||
func TestGetContext(t *testing.T) { | ||
ctx := context.Background() | ||
result := Get().GetContext() | ||
require.Equal(t, ctx, result) | ||
} | ||
|
||
func TestGetClock(t *testing.T) { | ||
clk := clock.NewRealClock() | ||
result := Get().GetClock() | ||
|
||
require.Equal(t, clk, result) | ||
} | ||
|
||
func TestWithMockClock(t *testing.T) { | ||
result := Get().SetMockClock() | ||
require.IsType(t, &clock.MockClock{}, result.clock) | ||
} | ||
|
||
func TestWithRealClock(t *testing.T) { | ||
result := Get().SetRealClock() | ||
require.IsType(t, &clock.RealClock{}, result.clock) | ||
} | ||
|
||
func TestWithContext(t *testing.T) { | ||
ctx := context.Background() | ||
result := Get().WithContext(ctx) | ||
|
||
require.Equal(t, ctx, result.GetContext()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.