ScuttleBot
perf: remove SAMODE, strip voice lists from static channels SAMODE was causing slow startup and didn't reliably apply modes. ChanServ AMODE persists across restarts so voice lists in static channel config are unnecessary after first provisioning. Removed SAMODE entirely. Removed voice lists from topology config. Startup now only sends ChanServ REGISTER + TOPIC per channel (no mode commands), making provisioning near-instant.
Commit
c363d3dbd9eca65b35ff38288bec310c7f7711e0ac0f44b4c430d60c2dfdf136
Parent
1ff6cfa7edabfb7…
1 file changed
+11
-23
+11
-23
| --- internal/topology/topology.go | ||
| +++ internal/topology/topology.go | ||
| @@ -216,33 +216,21 @@ | ||
| 216 | 216 | // Apply channel modes (e.g. +m for moderated). |
| 217 | 217 | for _, mode := range ch.Modes { |
| 218 | 218 | m.client.Cmd.Mode(ch.Name, mode) |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | - // Fire mode grants asynchronously — don't block provisioning. | |
| 222 | - // ChanServ AMODE persists and auto-applies on join. | |
| 223 | - // SAMODE is immediate but only works for nicks already in the channel, | |
| 224 | - // so we delay it to give bots time to connect first. | |
| 225 | - go func(name string, ops, voice []string) { | |
| 226 | - // Set persistent AMODE first (works regardless of presence). | |
| 227 | - for _, nick := range ops { | |
| 228 | - m.chanserv("AMODE %s +o %s", name, nick) | |
| 229 | - } | |
| 230 | - for _, nick := range voice { | |
| 231 | - m.chanserv("AMODE %s +v %s", name, nick) | |
| 232 | - } | |
| 233 | - // Delay SAMODE to apply modes to bots that connected after provisioning. | |
| 234 | - if m.operPass != "" && m.client != nil { | |
| 235 | - time.Sleep(30 * time.Second) | |
| 236 | - for _, nick := range ops { | |
| 237 | - m.client.Cmd.SendRawf("SAMODE %s +o %s", name, nick) | |
| 238 | - } | |
| 239 | - for _, nick := range voice { | |
| 240 | - m.client.Cmd.SendRawf("SAMODE %s +v %s", name, nick) | |
| 241 | - } | |
| 242 | - } | |
| 243 | - }(ch.Name, ch.Ops, ch.Voice) | |
| 221 | + // Fire ChanServ AMODE grants asynchronously — persistent, auto-applied on join. | |
| 222 | + if len(ch.Ops) > 0 || len(ch.Voice) > 0 { | |
| 223 | + go func(name string, ops, voice []string) { | |
| 224 | + for _, nick := range ops { | |
| 225 | + m.chanserv("AMODE %s +o %s", name, nick) | |
| 226 | + } | |
| 227 | + for _, nick := range voice { | |
| 228 | + m.chanserv("AMODE %s +v %s", name, nick) | |
| 229 | + } | |
| 230 | + }(ch.Name, ch.Ops, ch.Voice) | |
| 231 | + } | |
| 244 | 232 | |
| 245 | 233 | if len(ch.Autojoin) > 0 { |
| 246 | 234 | m.Invite(ch.Name, ch.Autojoin) |
| 247 | 235 | } |
| 248 | 236 | |
| 249 | 237 |
| --- internal/topology/topology.go | |
| +++ internal/topology/topology.go | |
| @@ -216,33 +216,21 @@ | |
| 216 | // Apply channel modes (e.g. +m for moderated). |
| 217 | for _, mode := range ch.Modes { |
| 218 | m.client.Cmd.Mode(ch.Name, mode) |
| 219 | } |
| 220 | |
| 221 | // Fire mode grants asynchronously — don't block provisioning. |
| 222 | // ChanServ AMODE persists and auto-applies on join. |
| 223 | // SAMODE is immediate but only works for nicks already in the channel, |
| 224 | // so we delay it to give bots time to connect first. |
| 225 | go func(name string, ops, voice []string) { |
| 226 | // Set persistent AMODE first (works regardless of presence). |
| 227 | for _, nick := range ops { |
| 228 | m.chanserv("AMODE %s +o %s", name, nick) |
| 229 | } |
| 230 | for _, nick := range voice { |
| 231 | m.chanserv("AMODE %s +v %s", name, nick) |
| 232 | } |
| 233 | // Delay SAMODE to apply modes to bots that connected after provisioning. |
| 234 | if m.operPass != "" && m.client != nil { |
| 235 | time.Sleep(30 * time.Second) |
| 236 | for _, nick := range ops { |
| 237 | m.client.Cmd.SendRawf("SAMODE %s +o %s", name, nick) |
| 238 | } |
| 239 | for _, nick := range voice { |
| 240 | m.client.Cmd.SendRawf("SAMODE %s +v %s", name, nick) |
| 241 | } |
| 242 | } |
| 243 | }(ch.Name, ch.Ops, ch.Voice) |
| 244 | |
| 245 | if len(ch.Autojoin) > 0 { |
| 246 | m.Invite(ch.Name, ch.Autojoin) |
| 247 | } |
| 248 | |
| 249 |
| --- internal/topology/topology.go | |
| +++ internal/topology/topology.go | |
| @@ -216,33 +216,21 @@ | |
| 216 | // Apply channel modes (e.g. +m for moderated). |
| 217 | for _, mode := range ch.Modes { |
| 218 | m.client.Cmd.Mode(ch.Name, mode) |
| 219 | } |
| 220 | |
| 221 | // Fire ChanServ AMODE grants asynchronously — persistent, auto-applied on join. |
| 222 | if len(ch.Ops) > 0 || len(ch.Voice) > 0 { |
| 223 | go func(name string, ops, voice []string) { |
| 224 | for _, nick := range ops { |
| 225 | m.chanserv("AMODE %s +o %s", name, nick) |
| 226 | } |
| 227 | for _, nick := range voice { |
| 228 | m.chanserv("AMODE %s +v %s", name, nick) |
| 229 | } |
| 230 | }(ch.Name, ch.Ops, ch.Voice) |
| 231 | } |
| 232 | |
| 233 | if len(ch.Autojoin) > 0 { |
| 234 | m.Invite(ch.Name, ch.Autojoin) |
| 235 | } |
| 236 | |
| 237 |