Skip to content

Commit

Permalink
refactor(loader): Change the running state from bool to atomic int32 …
Browse files Browse the repository at this point in the history
…for thread safety

Updated the Loader struct to use atomic operations for the running state, ensuring safe concurrent access. Modified the Start and Stop methods to reflect this change. Updated tests to check the running state correctly.
  • Loading branch information
tab committed Oct 13, 2024
1 parent 3720097 commit b6a7e40
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 53 deletions.
9 changes: 5 additions & 4 deletions internal/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@ package loader

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

type Loader struct {
running bool
running int32
}

func New() *Loader {
return &Loader{}
}

func (l *Loader) Start() {
l.running = true
atomic.StoreInt32(&l.running, 1)

chars := []rune{'|', '/', '-', '\\'}
idx := 0

go func() {
for l.running {
for atomic.LoadInt32(&l.running) == 1 {
fmt.Printf("\r%c Loading...", chars[idx])
idx = (idx + 1) % len(chars)
time.Sleep(100 * time.Millisecond)
Expand All @@ -29,6 +30,6 @@ func (l *Loader) Start() {
}

func (l *Loader) Stop() {
l.running = false
atomic.StoreInt32(&l.running, 0)
fmt.Printf("\r\033[K")
}
109 changes: 60 additions & 49 deletions internal/loader/loader_test.go
Original file line number Diff line number Diff line change
@@ -1,58 +1,69 @@
package loader

import (
"testing"
"time"
"sync/atomic"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
)

func Test_Start(t *testing.T) {
tests := []struct {
name string
waitTime time.Duration
expect bool
}{
{
name: "Running",
waitTime: 50 * time.Millisecond,
expect: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
loader := New()
loader.Start()
defer loader.Stop()

time.Sleep(tt.waitTime)
assert.Equal(t, tt.expect, loader.running)
})
}
func TestLoader_Start(t *testing.T) {
tests := []struct {
name string
waitTime time.Duration
expectRunning bool
}{
{
name: "Loader starts and runs",
waitTime: 200 * time.Millisecond,
expectRunning: true,
},
{
name: "Loader runs for a short time",
waitTime: 100 * time.Millisecond,
expectRunning: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := New()

l.Start()
time.Sleep(tt.waitTime)

running := atomic.LoadInt32(&l.running) == 1
assert.Equal(t, tt.expectRunning, running)

l.Stop()
})
}
}

func Test_Stop(t *testing.T) {
tests := []struct {
name string
waitTime time.Duration
expect bool
}{
{
name: "Stopped",
waitTime: 50 * time.Millisecond,
expect: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
loader := New()
loader.Start()
loader.Stop()

time.Sleep(tt.waitTime)
assert.Equal(t, tt.expect, loader.running)
})
}
func TestLoader_Stop(t *testing.T) {
tests := []struct {
name string
waitTime time.Duration
expectRunning bool
}{
{
name: "Loader stops after start",
waitTime: 100 * time.Millisecond,
expectRunning: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := New()

l.Start()
l.Stop()
time.Sleep(tt.waitTime)

running := atomic.LoadInt32(&l.running) == 1
assert.Equal(t, tt.expectRunning, running)
})
}
}

0 comments on commit b6a7e40

Please sign in to comment.