This repository has been archived by the owner on Oct 31, 2024. It is now read-only.
forked from 0xPolygon/polygon-edge
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EVM-687 Dial queue slots (0xPolygon#1601)
- Loading branch information
1 parent
4a083ca
commit 6e5cd75
Showing
3 changed files
with
106 additions
and
43 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package network | ||
|
||
import ( | ||
"context" | ||
) | ||
|
||
// Slots is synchronization structure | ||
// A routine can invoke the Take method, which will block until at least one slot becomes available | ||
// The Release method can be called by other routines to increase the number of available slots by one | ||
type Slots chan struct{} | ||
|
||
// NewSlots creates Slots object with maximal slots available | ||
func NewSlots(maximal int64) Slots { | ||
slots := make(Slots, maximal) | ||
// add slots | ||
for i := int64(0); i < maximal; i++ { | ||
slots <- struct{}{} | ||
} | ||
|
||
return slots | ||
} | ||
|
||
// Take takes slot if available or blocks until slot is available or context is done | ||
func (s Slots) Take(ctx context.Context) bool { | ||
select { | ||
case <-ctx.Done(): | ||
return true | ||
case <-s: | ||
return false | ||
} | ||
} | ||
|
||
// Release returns back one slot. If all slots are already released, nothing will happen | ||
func (s Slots) Release() { | ||
select { | ||
case s <- struct{}{}: | ||
default: // No slot available to release, do nothing | ||
} | ||
} |
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,41 @@ | ||
package network | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestSlots(t *testing.T) { | ||
t.Parallel() | ||
|
||
slots := NewSlots(4) | ||
|
||
for i := 0; i < 4; i++ { | ||
slots.Release() // should do nothing | ||
} | ||
|
||
for i := 3; i >= 0; i-- { | ||
closed := slots.Take(context.Background()) | ||
assert.False(t, closed) | ||
} | ||
|
||
go func() { | ||
time.Sleep(time.Millisecond * 500) | ||
slots.Release() // return one slot after 500 milis | ||
time.Sleep(time.Millisecond * 500) | ||
slots.Release() // return another slot after 1 seconds | ||
}() | ||
|
||
tm := time.Now().UTC() | ||
|
||
closed1 := slots.Take(context.Background()) | ||
closed2 := slots.Take(context.Background()) | ||
|
||
assert.False(t, closed1) | ||
assert.GreaterOrEqual(t, time.Now().UTC(), tm.Add(time.Millisecond*500)) | ||
assert.False(t, closed2) | ||
assert.GreaterOrEqual(t, time.Now().UTC(), tm.Add(time.Millisecond*500*2)) | ||
} |