Skip to content

Commit

Permalink
Merge branch 'master' into bitget_api_creation
Browse files Browse the repository at this point in the history
  • Loading branch information
cranktakular committed Mar 26, 2024
2 parents a89c8cb + 05dec88 commit 19a3914
Show file tree
Hide file tree
Showing 20 changed files with 1,423 additions and 1,727 deletions.
14 changes: 6 additions & 8 deletions .github/workflows/proto-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ jobs:

- name: Setup build depends
run: |
go get github.com/grpc-ecosystem/grpc-gateway/v2/internal/[email protected]
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
go install google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
- uses: bufbuild/[email protected]
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
- uses: bufbuild/[email protected]

- name: buf generate
working-directory: ./gctrpc
Expand Down
2 changes: 1 addition & 1 deletion backtester/btrpc/btrpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

198 changes: 90 additions & 108 deletions backtester/btrpc/btrpc.pb.gw.go

Large diffs are not rendered by default.

50 changes: 31 additions & 19 deletions backtester/btrpc/btrpc_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 39 additions & 55 deletions common/timedmutex/timed_mutex.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,61 @@ package timedmutex

import (
"sync"
"sync/atomic"
"time"
)

// NewTimedMutex creates a new timed mutex with a
// specified duration
// TimedMutex is a blocking mutex which will unlock after a specified time
type TimedMutex struct {
// primary mutex is the main lock that will be unlocked after the duration
primary sync.Mutex
// secondary mutex is used to protect the timer
secondary sync.Mutex
timer *time.Timer
// primed is used to determine if the timer has been started this is
// slightly more performant than checking the timer directly and interacting
// with a RW mutex.
primed atomic.Bool
duration time.Duration
}

// NewTimedMutex creates a new timed mutex with a specified duration
func NewTimedMutex(length time.Duration) *TimedMutex {
return &TimedMutex{
duration: length,
}
return &TimedMutex{duration: length}
}

// LockForDuration will start a timer, lock the mutex,
// then allow the caller to continue
// LockForDuration will start a timer, lock the mutex, then allow the caller to continue
// After the duration, the mutex will be unlocked
func (t *TimedMutex) LockForDuration() {
var wg sync.WaitGroup
wg.Add(1)
go t.lockAndSetTimer(&wg)
wg.Wait()
}

func (t *TimedMutex) lockAndSetTimer(wg *sync.WaitGroup) {
t.mtx.Lock()
t.setTimer()
wg.Done()
t.primary.Lock()
if !t.primed.Swap(true) {
t.secondary.Lock()
t.timer = time.AfterFunc(t.duration, func() { t.primary.Unlock() })
t.secondary.Unlock()
} else {
// Timer C channel is not used with AfterFunc, so no need to drain.
t.secondary.Lock()
t.timer.Reset(t.duration)
t.secondary.Unlock()
}
}

// UnlockIfLocked will unlock the mutex if its currently locked
// Will return true if successfully unlocked
// UnlockIfLocked will unlock the mutex if its currently locked Will return true
// if successfully unlocked
func (t *TimedMutex) UnlockIfLocked() bool {
if t.isTimerNil() {
if !t.primed.Load() {
return false
}

if !t.stopTimer() {
return false
}
t.mtx.Unlock()
return true
}
t.secondary.Lock()
wasStoppedByCall := t.timer.Stop()
t.secondary.Unlock()

// stopTimer will return true if timer has been stopped by this command
// If the timer has expired, clear the channel
func (t *TimedMutex) stopTimer() bool {
t.timerLock.Lock()
defer t.timerLock.Unlock()
if !t.timer.Stop() {
select {
case <-t.timer.C:
default:
}
if !wasStoppedByCall {
// Timer has already fired and the mutex has been unlocked.
// Timer C channel is not used with AfterFunc, so no need to drain.
return false
}
t.primary.Unlock()
return true
}

// isTimerNil safely read locks to detect nil
func (t *TimedMutex) isTimerNil() bool {
t.timerLock.RLock()
isNil := t.timer == nil
t.timerLock.RUnlock()
return isNil
}

// setTimer safely locks and sets a timer
// which will automatically execute a mutex unlock
// once timer expires
func (t *TimedMutex) setTimer() {
t.timerLock.Lock()
t.timer = time.AfterFunc(t.duration, func() {
t.mtx.Unlock()
})
t.timerLock.Unlock()
}
33 changes: 32 additions & 1 deletion common/timedmutex/timed_mutex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,41 @@ import (
"time"
)

// 1000000 1074 ns/op 136 B/op 4 allocs/op (prev)
// 2423571 503.9 ns/op 0 B/op 0 allocs/op (current)
func BenchmarkTimedMutexTime(b *testing.B) {
tm := NewTimedMutex(20 * time.Millisecond)
tm := NewTimedMutex(0)
for i := 0; i < b.N; i++ {
tm.LockForDuration()
}
}

// 352309195 3.194 ns/op 0 B/op 0 allocs/op (prev)
// 927051118 1.298 ns/op 0 B/op 0 allocs/op
func BenchmarkTimedMutexTimeUnlockNotPrimed(b *testing.B) {
tm := NewTimedMutex(0)
for i := 0; i < b.N; i++ {
tm.UnlockIfLocked()
}
}

// 95322825 15.51 ns/op 0 B/op 0 allocs/op (prev)
// 239158972 4.621 ns/op 0 B/op 0 allocs/op
func BenchmarkTimedMutexTimeUnlockPrimed(b *testing.B) {
tm := NewTimedMutex(0)
tm.LockForDuration()
for i := 0; i < b.N; i++ {
tm.UnlockIfLocked()
}
}

// 1000000 1193 ns/op 136 B/op 4 allocs/op (prev)
// 38592405 36.12 ns/op 0 B/op 0 allocs/op
func BenchmarkTimedMutexTimeLinearInteraction(b *testing.B) {
tm := NewTimedMutex(0)
for i := 0; i < b.N; i++ {
tm.LockForDuration()
tm.UnlockIfLocked()
}
}

Expand Down
15 changes: 0 additions & 15 deletions common/timedmutex/timed_mutex_types.go

This file was deleted.

Loading

0 comments on commit 19a3914

Please sign in to comment.