github.com/nsqio/nsq@v1.3.0/nsqlookupd/registration_db_test.go (about) 1 package nsqlookupd 2 3 import ( 4 "math/rand" 5 "strconv" 6 "testing" 7 "time" 8 9 "github.com/nsqio/nsq/internal/test" 10 ) 11 12 func TestRegistrationDB(t *testing.T) { 13 sec30 := 30 * time.Second 14 beginningOfTime := time.Unix(1348797047, 0) 15 pi1 := &PeerInfo{beginningOfTime.UnixNano(), "1", "remote_addr:1", "host", "b_addr", 1, 2, "v1"} 16 pi2 := &PeerInfo{beginningOfTime.UnixNano(), "2", "remote_addr:2", "host", "b_addr", 2, 3, "v1"} 17 pi3 := &PeerInfo{beginningOfTime.UnixNano(), "3", "remote_addr:3", "host", "b_addr", 3, 4, "v1"} 18 p1 := &Producer{pi1, false, beginningOfTime} 19 p2 := &Producer{pi2, false, beginningOfTime} 20 p3 := &Producer{pi3, false, beginningOfTime} 21 p4 := &Producer{pi1, false, beginningOfTime} 22 23 db := NewRegistrationDB() 24 25 // add producers 26 db.AddProducer(Registration{"c", "a", ""}, p1) 27 db.AddProducer(Registration{"c", "a", ""}, p2) 28 db.AddProducer(Registration{"c", "a", "b"}, p2) 29 db.AddProducer(Registration{"d", "a", ""}, p3) 30 db.AddProducer(Registration{"t", "a", ""}, p4) 31 32 // find producers 33 r := db.FindRegistrations("c", "*", "").Keys() 34 test.Equal(t, 1, len(r)) 35 test.Equal(t, "a", r[0]) 36 37 p := db.FindProducers("t", "*", "") 38 t.Logf("%s", p) 39 test.Equal(t, 1, len(p)) 40 p = db.FindProducers("c", "*", "") 41 t.Logf("%s", p) 42 test.Equal(t, 2, len(p)) 43 p = db.FindProducers("c", "a", "") 44 t.Logf("%s", p) 45 test.Equal(t, 2, len(p)) 46 p = db.FindProducers("c", "*", "b") 47 t.Logf("%s", p) 48 test.Equal(t, 1, len(p)) 49 test.Equal(t, p2.peerInfo.id, p[0].peerInfo.id) 50 51 // filter by active 52 test.Equal(t, 0, len(p.FilterByActive(sec30, sec30))) 53 p2.peerInfo.lastUpdate = time.Now().UnixNano() 54 test.Equal(t, 1, len(p.FilterByActive(sec30, sec30))) 55 p = db.FindProducers("c", "*", "") 56 t.Logf("%s", p) 57 test.Equal(t, 1, len(p.FilterByActive(sec30, sec30))) 58 59 // tombstoning 60 fewSecAgo := time.Now().Add(-5 * time.Second).UnixNano() 61 p1.peerInfo.lastUpdate = fewSecAgo 62 p2.peerInfo.lastUpdate = fewSecAgo 63 test.Equal(t, 2, len(p.FilterByActive(sec30, sec30))) 64 p1.Tombstone() 65 test.Equal(t, 1, len(p.FilterByActive(sec30, sec30))) 66 time.Sleep(10 * time.Millisecond) 67 test.Equal(t, 2, len(p.FilterByActive(sec30, 5*time.Millisecond))) 68 // make sure we can still retrieve p1 from another registration see #148 69 test.Equal(t, 1, len(db.FindProducers("t", "*", "").FilterByActive(sec30, sec30))) 70 71 // keys and subkeys 72 k := db.FindRegistrations("c", "b", "").Keys() 73 test.Equal(t, 0, len(k)) 74 k = db.FindRegistrations("c", "a", "").Keys() 75 test.Equal(t, 1, len(k)) 76 test.Equal(t, "a", k[0]) 77 k = db.FindRegistrations("c", "*", "b").SubKeys() 78 test.Equal(t, 1, len(k)) 79 test.Equal(t, "b", k[0]) 80 81 // removing producers 82 db.RemoveProducer(Registration{"c", "a", ""}, p1.peerInfo.id) 83 p = db.FindProducers("c", "*", "*") 84 t.Logf("%s", p) 85 test.Equal(t, 1, len(p)) 86 87 db.RemoveProducer(Registration{"c", "a", ""}, p2.peerInfo.id) 88 db.RemoveProducer(Registration{"c", "a", "b"}, p2.peerInfo.id) 89 p = db.FindProducers("c", "*", "*") 90 t.Logf("%s", p) 91 test.Equal(t, 0, len(p)) 92 93 // do some key removals 94 k = db.FindRegistrations("c", "*", "*").Keys() 95 test.Equal(t, 2, len(k)) 96 db.RemoveRegistration(Registration{"c", "a", ""}) 97 db.RemoveRegistration(Registration{"c", "a", "b"}) 98 k = db.FindRegistrations("c", "*", "*").Keys() 99 test.Equal(t, 0, len(k)) 100 } 101 102 func fillRegDB(registrations int, producers int) *RegistrationDB { 103 regDB := NewRegistrationDB() 104 for i := 0; i < registrations; i++ { 105 regT := Registration{"topic", "t" + strconv.Itoa(i), ""} 106 regCa := Registration{"channel", "t" + strconv.Itoa(i), "ca" + strconv.Itoa(i)} 107 regCb := Registration{"channel", "t" + strconv.Itoa(i), "cb" + strconv.Itoa(i)} 108 for j := 0; j < producers; j++ { 109 p := Producer{ 110 peerInfo: &PeerInfo{ 111 id: "p" + strconv.Itoa(j), 112 }, 113 } 114 regDB.AddProducer(regT, &p) 115 regDB.AddProducer(regCa, &p) 116 regDB.AddProducer(regCb, &p) 117 } 118 } 119 return regDB 120 } 121 122 func benchmarkLookupRegistrations(b *testing.B, registrations int, producers int) { 123 regDB := fillRegDB(registrations, producers) 124 b.ResetTimer() 125 for i := 0; i < b.N; i++ { 126 j := strconv.Itoa(rand.Intn(producers)) 127 _ = regDB.LookupRegistrations("p" + j) 128 } 129 } 130 131 func benchmarkRegister(b *testing.B, registrations int, producers int) { 132 for i := 0; i < b.N; i++ { 133 _ = fillRegDB(registrations, producers) 134 } 135 } 136 137 func benchmarkDoLookup(b *testing.B, registrations int, producers int) { 138 regDB := fillRegDB(registrations, producers) 139 b.ResetTimer() 140 for i := 0; i < b.N; i++ { 141 topic := "t" + strconv.Itoa(rand.Intn(registrations)) 142 _ = regDB.FindRegistrations("topic", topic, "") 143 _ = regDB.FindRegistrations("channel", topic, "*").SubKeys() 144 _ = regDB.FindProducers("topic", topic, "") 145 } 146 } 147 148 func BenchmarkLookupRegistrations8x8(b *testing.B) { 149 benchmarkLookupRegistrations(b, 8, 8) 150 } 151 152 func BenchmarkLookupRegistrations8x64(b *testing.B) { 153 benchmarkLookupRegistrations(b, 8, 64) 154 } 155 156 func BenchmarkLookupRegistrations64x64(b *testing.B) { 157 benchmarkLookupRegistrations(b, 64, 64) 158 } 159 160 func BenchmarkLookupRegistrations64x512(b *testing.B) { 161 benchmarkLookupRegistrations(b, 64, 512) 162 } 163 164 func BenchmarkLookupRegistrations512x512(b *testing.B) { 165 benchmarkLookupRegistrations(b, 512, 512) 166 } 167 168 func BenchmarkLookupRegistrations512x2048(b *testing.B) { 169 benchmarkLookupRegistrations(b, 512, 2048) 170 } 171 172 func BenchmarkRegister8x8(b *testing.B) { 173 benchmarkRegister(b, 8, 8) 174 } 175 176 func BenchmarkRegister8x64(b *testing.B) { 177 benchmarkRegister(b, 8, 64) 178 } 179 180 func BenchmarkRegister64x64(b *testing.B) { 181 benchmarkRegister(b, 64, 64) 182 } 183 184 func BenchmarkRegister64x512(b *testing.B) { 185 benchmarkRegister(b, 64, 512) 186 } 187 188 func BenchmarkRegister512x512(b *testing.B) { 189 benchmarkRegister(b, 512, 512) 190 } 191 192 func BenchmarkRegister512x2048(b *testing.B) { 193 benchmarkRegister(b, 512, 2048) 194 } 195 196 func BenchmarkDoLookup8x8(b *testing.B) { 197 benchmarkDoLookup(b, 8, 8) 198 } 199 200 func BenchmarkDoLookup8x64(b *testing.B) { 201 benchmarkDoLookup(b, 8, 64) 202 } 203 204 func BenchmarkDoLookup64x64(b *testing.B) { 205 benchmarkDoLookup(b, 64, 64) 206 } 207 208 func BenchmarkDoLookup64x512(b *testing.B) { 209 benchmarkDoLookup(b, 64, 512) 210 } 211 212 func BenchmarkDoLookup512x512(b *testing.B) { 213 benchmarkDoLookup(b, 512, 512) 214 } 215 216 func BenchmarkDoLookup512x2048(b *testing.B) { 217 benchmarkDoLookup(b, 512, 2048) 218 }