Skip to content

Commit

Permalink
Add election test for background routine handling
Browse files Browse the repository at this point in the history
  • Loading branch information
krapie committed Jul 8, 2023
1 parent 4811338 commit dad28f9
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
2 changes: 1 addition & 1 deletion server/backend/database/mongo/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,7 @@ func (c *Client) RenewLeaderLease(
// FindLeader returns the leader hostname for the given leaseLockName.
func (c *Client) FindLeader(ctx context.Context, leaseLockName string) (*string, error) {
electionInfo := &struct {
ElectionId string `bson:"election_id"`
ElectionID string `bson:"election_id"`
LeaderID string `bson:"leader_id"`
LeaseExpireAt gotime.Time `bson:"lease_expire_at"`
}{}
Expand Down
2 changes: 2 additions & 0 deletions server/backend/database/mongo/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package mongo_test

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"

Expand Down
10 changes: 9 additions & 1 deletion server/backend/election/mongo/election.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package mongo

import (
"context"
"sync"
"time"

"github.com/yorkie-team/yorkie/server/backend/database"
Expand All @@ -33,6 +34,8 @@ type Elector struct {

ctx context.Context
cancelFunc context.CancelFunc

wg sync.WaitGroup
}

// NewElector creates a new elector instance.
Expand Down Expand Up @@ -70,6 +73,7 @@ func (e *Elector) StartElection(
// Stop stops all leader elections.
func (e *Elector) Stop() error {
e.cancelFunc()
e.wg.Wait()

return nil
}
Expand All @@ -91,7 +95,11 @@ func (e *Elector) run(
}

if acquired {
go onStartLeading(ctx)
go func() {
e.wg.Add(1)
onStartLeading(ctx)
e.wg.Done()
}()
logging.From(ctx).Infof(
"leader elected: %s", e.hostname,
)
Expand Down
40 changes: 31 additions & 9 deletions server/backend/election/mongo/election_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package mongo_test

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/yorkie-team/yorkie/server/backend/database/mongo"
mongoelection "github.com/yorkie-team/yorkie/server/backend/election/mongo"
"github.com/yorkie-team/yorkie/test/helper"
"testing"
"time"
)

var (
Expand Down Expand Up @@ -43,6 +45,7 @@ func TestElection(t *testing.T) {
assert.NoError(t, electorA.StartElection(leaseLockName, helper.LeaseDuration, normalTask, stopTask))
assert.NoError(t, electorB.StartElection(leaseLockName, helper.LeaseDuration, normalTask, stopTask))
assert.NoError(t, electorC.StartElection(leaseLockName, helper.LeaseDuration, normalTask, stopTask))
time.Sleep(helper.LeaseDuration)

// elector A will be the leader because it is the first to start the election.
leader, err := db.FindLeader(context.Background(), leaseLockName)
Expand Down Expand Up @@ -71,19 +74,19 @@ func TestElection(t *testing.T) {
t.Run("lease renewal while handling a a long task test", func(t *testing.T) {
leaseLockName := t.Name()
longTask := func(ctx context.Context) {
time.Sleep(helper.LeaseDuration * 2)
time.Sleep(helper.LeaseDuration * 4)
}

electorA := mongoelection.NewElector("A", db)
electorB := mongoelection.NewElector("B", db)
electorC := mongoelection.NewElector("C", db)

assert.NoError(t, electorA.StartElection(leaseLockName, helper.LeaseDuration, longTask, stopTask))
assert.NoError(t, electorB.StartElection(leaseLockName, helper.LeaseDuration, normalTask, stopTask))
assert.NoError(t, electorC.StartElection(leaseLockName, helper.LeaseDuration, normalTask, stopTask))
assert.NoError(t, electorB.StartElection(leaseLockName, helper.LeaseDuration, longTask, stopTask))
assert.NoError(t, electorC.StartElection(leaseLockName, helper.LeaseDuration, longTask, stopTask))

// check if elector A is still the leader
time.Sleep(helper.LeaseDuration)
// wait for lease expiration and check if elector A is still the leader while handling a long task
time.Sleep(helper.LeaseDuration * 2)

leader, err := db.FindLeader(context.Background(), leaseLockName)
assert.NoError(t, err)
Expand All @@ -92,7 +95,26 @@ func TestElection(t *testing.T) {
})

t.Run("handle background routines when shutting down the server test", func(t *testing.T) {
// TODO(krapie): find the way to gradually close election routines
t.Skip()
shutdownCh := make(chan struct{})

isTaskDone := false
longTask := func(ctx context.Context) {
close(shutdownCh)
time.Sleep(helper.LeaseDuration)
isTaskDone = true
}

elector := mongoelection.NewElector("A", db)
assert.NoError(t, elector.StartElection(t.Name(), helper.LeaseDuration, longTask, stopTask))

// if receive shutdown signal, stop elector
select {
case <-shutdownCh:
assert.NoError(t, elector.Stop())
}

// check if the task is done
// this means that the background routine is handled properly after server(elector) is stopped
assert.Equal(t, true, isTaskDone)
})
}

1 comment on commit dad28f9

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go Benchmark

Benchmark suite Current: dad28f9 Previous: 070b6bf Ratio
BenchmarkDocument/constructor_test - ns/op 1569 ns/op 1275 ns/op 1.23
BenchmarkDocument/constructor_test - B/op 752 B/op 752 B/op 1
BenchmarkDocument/constructor_test - allocs/op 12 allocs/op 12 allocs/op 1
BenchmarkDocument/status_test - ns/op 642.5 ns/op 946.9 ns/op 0.68
BenchmarkDocument/status_test - B/op 720 B/op 720 B/op 1
BenchmarkDocument/status_test - allocs/op 10 allocs/op 10 allocs/op 1
BenchmarkDocument/equals_test - ns/op 7478 ns/op 7299 ns/op 1.02
BenchmarkDocument/equals_test - B/op 5072 B/op 5072 B/op 1
BenchmarkDocument/equals_test - allocs/op 85 allocs/op 85 allocs/op 1
BenchmarkDocument/nested_update_test - ns/op 21073 ns/op 21177 ns/op 1.00
BenchmarkDocument/nested_update_test - B/op 11033 B/op 11033 B/op 1
BenchmarkDocument/nested_update_test - allocs/op 235 allocs/op 235 allocs/op 1
BenchmarkDocument/delete_test - ns/op 27588 ns/op 28530 ns/op 0.97
BenchmarkDocument/delete_test - B/op 14162 B/op 14162 B/op 1
BenchmarkDocument/delete_test - allocs/op 310 allocs/op 310 allocs/op 1
BenchmarkDocument/object_test - ns/op 9819 ns/op 9671 ns/op 1.02
BenchmarkDocument/object_test - B/op 5792 B/op 5792 B/op 1
BenchmarkDocument/object_test - allocs/op 97 allocs/op 97 allocs/op 1
BenchmarkDocument/array_test - ns/op 34966 ns/op 34819 ns/op 1.00
BenchmarkDocument/array_test - B/op 10890 B/op 10889 B/op 1.00
BenchmarkDocument/array_test - allocs/op 251 allocs/op 251 allocs/op 1
BenchmarkDocument/text_test - ns/op 37838 ns/op 37792 ns/op 1.00
BenchmarkDocument/text_test - B/op 14058 B/op 14058 B/op 1
BenchmarkDocument/text_test - allocs/op 456 allocs/op 456 allocs/op 1
BenchmarkDocument/text_composition_test - ns/op 38097 ns/op 38249 ns/op 1.00
BenchmarkDocument/text_composition_test - B/op 17539 B/op 17538 B/op 1.00
BenchmarkDocument/text_composition_test - allocs/op 461 allocs/op 461 allocs/op 1
BenchmarkDocument/rich_text_test - ns/op 100013 ns/op 102928 ns/op 0.97
BenchmarkDocument/rich_text_test - B/op 36007 B/op 36015 B/op 1.00
BenchmarkDocument/rich_text_test - allocs/op 1108 allocs/op 1108 allocs/op 1
BenchmarkDocument/counter_test - ns/op 19811 ns/op 19762 ns/op 1.00
BenchmarkDocument/counter_test - B/op 9058 B/op 9057 B/op 1.00
BenchmarkDocument/counter_test - allocs/op 212 allocs/op 212 allocs/op 1
BenchmarkDocument/text_edit_gc_100 - ns/op 4155788 ns/op 4040516 ns/op 1.03
BenchmarkDocument/text_edit_gc_100 - B/op 1552688 B/op 1552537 B/op 1.00
BenchmarkDocument/text_edit_gc_100 - allocs/op 17149 allocs/op 17147 allocs/op 1.00
BenchmarkDocument/text_edit_gc_1000 - ns/op 316014955 ns/op 316295025 ns/op 1.00
BenchmarkDocument/text_edit_gc_1000 - B/op 136648620 B/op 136642972 B/op 1.00
BenchmarkDocument/text_edit_gc_1000 - allocs/op 210767 allocs/op 210741 allocs/op 1.00
BenchmarkDocument/text_split_gc_100 - ns/op 4648118 ns/op 4596780 ns/op 1.01
BenchmarkDocument/text_split_gc_100 - B/op 2217576 B/op 2216867 B/op 1.00
BenchmarkDocument/text_split_gc_100 - allocs/op 16577 allocs/op 16572 allocs/op 1.00
BenchmarkDocument/text_split_gc_1000 - ns/op 413018773 ns/op 368857070 ns/op 1.12
BenchmarkDocument/text_split_gc_1000 - B/op 214848322 B/op 214861816 B/op 1.00
BenchmarkDocument/text_split_gc_1000 - allocs/op 211404 allocs/op 211441 allocs/op 1.00
BenchmarkDocument/text_delete_all_10000 - ns/op 16960775 ns/op 21021034 ns/op 0.81
BenchmarkDocument/text_delete_all_10000 - B/op 5905059 B/op 5904710 B/op 1.00
BenchmarkDocument/text_delete_all_10000 - allocs/op 41126 allocs/op 41123 allocs/op 1.00
BenchmarkDocument/text_delete_all_100000 - ns/op 211008217 ns/op 280500940 ns/op 0.75
BenchmarkDocument/text_delete_all_100000 - B/op 53855901 B/op 53838868 B/op 1.00
BenchmarkDocument/text_delete_all_100000 - allocs/op 416066 allocs/op 415985 allocs/op 1.00
BenchmarkDocument/text_100 - ns/op 303552 ns/op 326751 ns/op 0.93
BenchmarkDocument/text_100 - B/op 117749 B/op 117749 B/op 1
BenchmarkDocument/text_100 - allocs/op 5064 allocs/op 5064 allocs/op 1
BenchmarkDocument/text_1000 - ns/op 3305501 ns/op 3531932 ns/op 0.94
BenchmarkDocument/text_1000 - B/op 1152349 B/op 1152360 B/op 1.00
BenchmarkDocument/text_1000 - allocs/op 50068 allocs/op 50068 allocs/op 1
BenchmarkDocument/array_1000 - ns/op 1718980 ns/op 1783562 ns/op 0.96
BenchmarkDocument/array_1000 - B/op 1102202 B/op 1101945 B/op 1.00
BenchmarkDocument/array_1000 - allocs/op 11855 allocs/op 11854 allocs/op 1.00
BenchmarkDocument/array_10000 - ns/op 19300267 ns/op 20886913 ns/op 0.92
BenchmarkDocument/array_10000 - B/op 9906222 B/op 9905648 B/op 1.00
BenchmarkDocument/array_10000 - allocs/op 120705 allocs/op 120704 allocs/op 1.00
BenchmarkDocument/array_gc_100 - ns/op 179996 ns/op 182314 ns/op 0.99
BenchmarkDocument/array_gc_100 - B/op 97404 B/op 97418 B/op 1.00
BenchmarkDocument/array_gc_100 - allocs/op 1226 allocs/op 1226 allocs/op 1
BenchmarkDocument/array_gc_1000 - ns/op 1947172 ns/op 2023966 ns/op 0.96
BenchmarkDocument/array_gc_1000 - B/op 1169592 B/op 1169557 B/op 1.00
BenchmarkDocument/array_gc_1000 - allocs/op 12889 allocs/op 12889 allocs/op 1
BenchmarkDocument/counter_1000 - ns/op 266915 ns/op 291234 ns/op 0.92
BenchmarkDocument/counter_1000 - B/op 197876 B/op 197876 B/op 1
BenchmarkDocument/counter_1000 - allocs/op 6490 allocs/op 6490 allocs/op 1
BenchmarkDocument/counter_10000 - ns/op 2941458 ns/op 3160261 ns/op 0.93
BenchmarkDocument/counter_10000 - B/op 2164797 B/op 2164821 B/op 1.00
BenchmarkDocument/counter_10000 - allocs/op 69497 allocs/op 69497 allocs/op 1
BenchmarkDocument/object_1000 - ns/op 1887590 ns/op 1916070 ns/op 0.99
BenchmarkDocument/object_1000 - B/op 1450444 B/op 1450515 B/op 1.00
BenchmarkDocument/object_1000 - allocs/op 9901 allocs/op 9901 allocs/op 1
BenchmarkDocument/object_10000 - ns/op 21887933 ns/op 24081969 ns/op 0.91
BenchmarkDocument/object_10000 - B/op 12368881 B/op 12370050 B/op 1.00
BenchmarkDocument/object_10000 - allocs/op 101205 allocs/op 101208 allocs/op 1.00
BenchmarkRPC/client_to_server - ns/op 412068885 ns/op 454195849 ns/op 0.91
BenchmarkRPC/client_to_server - B/op 18911333 B/op 18895277 B/op 1.00
BenchmarkRPC/client_to_server - allocs/op 308332 allocs/op 307856 allocs/op 1.00
BenchmarkRPC/client_to_client_via_server - ns/op 687178061 ns/op 795188382 ns/op 0.86
BenchmarkRPC/client_to_client_via_server - B/op 34747956 B/op 34158392 B/op 1.02
BenchmarkRPC/client_to_client_via_server - allocs/op 569310 allocs/op 557902 allocs/op 1.02
BenchmarkRPC/attach_large_document - ns/op 1642364524 ns/op 1613558357 ns/op 1.02
BenchmarkRPC/attach_large_document - B/op 2152360416 B/op 2156784120 B/op 1.00
BenchmarkRPC/attach_large_document - allocs/op 10772 allocs/op 10070 allocs/op 1.07
BenchmarkRPC/adminCli_to_server - ns/op 528386138 ns/op 566988205 ns/op 0.93
BenchmarkRPC/adminCli_to_server - B/op 20383872 B/op 20392732 B/op 1.00
BenchmarkRPC/adminCli_to_server - allocs/op 321571 allocs/op 321623 allocs/op 1.00
BenchmarkLocker - ns/op 128.2 ns/op 124.5 ns/op 1.03
BenchmarkLocker - B/op 16 B/op 16 B/op 1
BenchmarkLocker - allocs/op 1 allocs/op 1 allocs/op 1
BenchmarkLockerParallel - ns/op 114.6 ns/op 135.9 ns/op 0.84
BenchmarkLockerParallel - B/op 0 B/op 0 B/op NaN
BenchmarkLockerParallel - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkLockerMoreKeys - ns/op 367 ns/op 319.9 ns/op 1.15
BenchmarkLockerMoreKeys - B/op 14 B/op 14 B/op 1
BenchmarkLockerMoreKeys - allocs/op 0 allocs/op 0 allocs/op NaN
BenchmarkSync/memory_sync_10_test - ns/op 7130 ns/op 7623 ns/op 0.94
BenchmarkSync/memory_sync_10_test - B/op 1341 B/op 1338 B/op 1.00
BenchmarkSync/memory_sync_10_test - allocs/op 39 allocs/op 39 allocs/op 1
BenchmarkSync/memory_sync_100_test - ns/op 59127 ns/op 67864 ns/op 0.87
BenchmarkSync/memory_sync_100_test - B/op 9089 B/op 8876 B/op 1.02
BenchmarkSync/memory_sync_100_test - allocs/op 298 allocs/op 285 allocs/op 1.05
BenchmarkSync/memory_sync_1000_test - ns/op 607310 ns/op 675295 ns/op 0.90
BenchmarkSync/memory_sync_1000_test - B/op 84007 B/op 81640 B/op 1.03
BenchmarkSync/memory_sync_1000_test - allocs/op 2724 allocs/op 2574 allocs/op 1.06
BenchmarkSync/memory_sync_10000_test - ns/op 6635898 ns/op 7464279 ns/op 0.89
BenchmarkSync/memory_sync_10000_test - B/op 869399 B/op 851108 B/op 1.02
BenchmarkSync/memory_sync_10000_test - allocs/op 27800 allocs/op 26725 allocs/op 1.04
BenchmarkTextEditing - ns/op 24186498904 ns/op 27333456807 ns/op 0.88
BenchmarkTextEditing - B/op 8436470432 B/op 8436351072 B/op 1.00
BenchmarkTextEditing - allocs/op 19836779 allocs/op 19836085 allocs/op 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.