github.com/metaworking/channeld@v0.7.3/pkg/channeld/subscription_test.go (about) 1 package channeld 2 3 import ( 4 "math/rand" 5 "sync" 6 "testing" 7 8 "github.com/metaworking/channeld/pkg/channeldpb" 9 "github.com/metaworking/channeld/pkg/common" 10 "github.com/stretchr/testify/assert" 11 "go.uber.org/zap" 12 ) 13 14 func init() { 15 InitLogs() 16 InitChannels() 17 } 18 19 func TestSubscribeToChannel(t *testing.T) { 20 c1 := addTestConnection(channeldpb.ConnectionType_SERVER) 21 22 assert.NotNil(t, globalChannel) 23 // Can't create the GLOBAL channel 24 _, err := CreateChannel(channeldpb.ChannelType_GLOBAL, nil) 25 assert.Error(t, err) 26 // By default, the GLOBAL channel has no owner 27 assert.True(t, !globalChannel.HasOwner()) 28 29 globalChannel.SetOwner(c1) 30 shouldSend := false 31 _, shouldSend = c1.SubscribeToChannel(globalChannel, nil) 32 assert.Contains(t, globalChannel.subscribedConnections, c1) 33 assert.True(t, shouldSend) 34 35 // Subscribe again 36 _, shouldSend = c1.SubscribeToChannel(globalChannel, nil) 37 assert.Contains(t, globalChannel.subscribedConnections, c1) 38 assert.False(t, shouldSend) 39 40 // Subscribe with different DataAccess 41 _, shouldSend = c1.SubscribeToChannel(globalChannel, &channeldpb.ChannelSubscriptionOptions{ 42 DataAccess: Pointer(channeldpb.ChannelDataAccess_WRITE_ACCESS), 43 }) 44 assert.True(t, shouldSend) 45 } 46 47 func randomChannelId(maxChId int) common.ChannelId { 48 // [0, 999] 49 chId := rand.Intn(maxChId) //time.Now().Nanosecond() % (maxChId - 1) 50 // [1, 1000] 51 return common.ChannelId(chId + 1) 52 } 53 54 func BenchmarkHandoverEntitySub(b *testing.B) { 55 // Disable logging 56 SetLogLevel(zap.FatalLevel) 57 58 CONN_NUM := 1000 59 ENTITY_CHANNEL_NUM := 1000 60 SPATIAL_CHANNEL_NUM := 15 * 15 61 CONN_PER_GRID := CONN_NUM / SPATIAL_CHANNEL_NUM 62 63 conns := make([]*Connection, CONN_NUM) 64 for i := 0; i < CONN_NUM; i++ { 65 conns[i] = addTestConnection(channeldpb.ConnectionType_CLIENT) //&Connection{id: ConnectionId(i), connectionType: channeldpb.ConnectionType_CLIENT} 66 67 } 68 69 for i := 0; i < ENTITY_CHANNEL_NUM; i++ { 70 CreateChannel(channeldpb.ChannelType_ENTITY, conns[i]) 71 } 72 73 b.ResetTimer() 74 75 for i := 0; i < b.N; i++ { 76 for _, conn := range conns { 77 // Every client subscribes to 3 spatial channels and unsubscribes from 3 spatial channels 78 for nSub := 0; nSub < 3*CONN_PER_GRID; nSub++ { 79 conn.SubscribeToChannel(GetChannel(randomChannelId(ENTITY_CHANNEL_NUM)), nil) 80 } 81 for nUnsub := 0; nUnsub < 3*CONN_PER_GRID; nUnsub++ { 82 conn.UnsubscribeFromChannel(GetChannel(randomChannelId(ENTITY_CHANNEL_NUM))) 83 } 84 } 85 } 86 } 87 88 /* 89 Result: 90 BenchmarkHandoverEntitySub-20 81 12666246 ns/op 7495425 B/op 100522 allocs/op 91 1000 clients handing over at the same time takes 13ms - Acceptable 92 7.5MB / 100K allocs - A bit too much 93 */ 94 95 func BenchmarkHandoverEntitySubAsync(b *testing.B) { 96 // Disable logging 97 SetLogLevel(zap.FatalLevel) 98 99 CONN_NUM := 1000 100 ENTITY_CHANNEL_NUM := 1000 101 SPATIAL_CHANNEL_NUM := 15 * 15 102 CONN_PER_GRID := CONN_NUM / SPATIAL_CHANNEL_NUM 103 104 conns := make([]*Connection, CONN_NUM) 105 for i := 0; i < CONN_NUM; i++ { 106 conns[i] = addTestConnection(channeldpb.ConnectionType_CLIENT) //&Connection{id: ConnectionId(i), connectionType: channeldpb.ConnectionType_CLIENT} 107 108 } 109 110 for i := 0; i < ENTITY_CHANNEL_NUM; i++ { 111 CreateChannel(channeldpb.ChannelType_ENTITY, conns[i]) 112 } 113 114 b.ResetTimer() 115 116 for i := 0; i < b.N; i++ { 117 wg := sync.WaitGroup{} 118 for s := 0; s < SPATIAL_CHANNEL_NUM; s++ { 119 gridIndex := s 120 wg.Add(1) 121 go func() { 122 for nConn := 0; nConn < CONN_PER_GRID; nConn++ { 123 conn := conns[gridIndex*CONN_PER_GRID+nConn] 124 // Every client subscribes to 3 spatial channels and unsubscribes from 3 spatial channels 125 for nSub := 0; nSub < 3*CONN_PER_GRID; nSub++ { 126 conn.SubscribeToChannel(GetChannel(randomChannelId(ENTITY_CHANNEL_NUM)), nil) 127 } 128 for nUnsub := 0; nUnsub < 3*CONN_PER_GRID; nUnsub++ { 129 conn.UnsubscribeFromChannel(GetChannel(randomChannelId(ENTITY_CHANNEL_NUM))) 130 } 131 } 132 wg.Done() 133 }() 134 } 135 wg.Wait() 136 } 137 } 138 139 /* 140 // Result: 141 BenchmarkHandoverEntitySubAsync-20 147 9056136 ns/op 5960059 B/op 82705 allocs/op 142 1000 clients handing over at the same time takes 9ms - Acceptable 143 6MB / 82K allocs - A bit too much 144 */