Don't send WhoList within 15 seconds of server start
To help alleviate rocky chat server reboots, WhoList messages will be withheld in the first 15 seconds from server start. When a lot of chatters were online during a reboot (e.g. 50 or more), they would all try and reconnect after 5 seconds and each login was broadcasting Who List updates to everybody else logged in. With the surge of logins in a short time, these WhoList messages would fill up the buffers of each recipient, kicking them offline for being too slow to keep up with messages; only for that recipient to reconnect again. The average user may have experienced 2 or 3 disconnects when the chat server reboots. To help alleviate the spam of messages being sent out: * Presence messages are withheld for the first 30 seconds ("has joined the room" notifications) * Now, WhoList messages are withheld for the first 15 seconds. After 16 seconds of uptime, the server will send a WhoList to everybody currently online to catch them up. To accommodate this, the front-end will show a spinner and say "Waiting for Who List..." when the page is connected but no WhoList has been received yet. Under normal operation, this spinner won't be visible beyond a brief moment as a WhoList is normally sent upon joining the chat.
This commit is contained in:
parent
3180d2ddf9
commit
09da9fa23d
|
@ -77,5 +77,16 @@ func (s *Server) ListenAndServe(address string) error {
|
|||
// Run the polling user idle kicker.
|
||||
s.upSince = time.Now()
|
||||
go s.KickIdlePollUsers()
|
||||
go s.sendWhoListAfterReady()
|
||||
return http.ListenAndServe(address, s.mux)
|
||||
}
|
||||
|
||||
// Send first WhoList update 15 seconds after the server reboots. This is in case a lot of chatters
|
||||
// are online during a reboot: we avoid broadcasting Presence for 30 seconds and WhoList for 15 to
|
||||
// reduce chatter and avoid kicking clients offline repeatedly for filling up their message buffer
|
||||
// as everyone rejoins the chat all at once.
|
||||
func (s *Server) sendWhoListAfterReady() {
|
||||
time.Sleep(16 * time.Second)
|
||||
log.Info("Up 15 seconds, sending WhoList to any online chatters")
|
||||
s.SendWhoList()
|
||||
}
|
||||
|
|
|
@ -429,6 +429,18 @@ func (s *Server) SendTo(username string, msg messages.Message) error {
|
|||
|
||||
// SendWhoList broadcasts the connected members to everybody in the room.
|
||||
func (s *Server) SendWhoList() {
|
||||
|
||||
// Don't send WhoList messages in the first 15 seconds of the server launch. This is to minimize
|
||||
// messages sent during a server reboot if a lot of chatters were online: Presence messages are
|
||||
// suppressed for 30 seconds, WhoList updates for 15, so that each user who reconnects doesn't
|
||||
// spam updates to every other user, which would fill their message buffer and kick them off and
|
||||
// makes for a rocky reboot. Instead: the server will send a WhoList to everyone at the 15 second
|
||||
// mark, and then send them normally from then on.
|
||||
if time.Since(s.upSince) < 15*time.Second {
|
||||
log.Debug("skip sending WhoList messages within 15 seconds of server reboot")
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
subscribers = s.IterSubscribers()
|
||||
usernames = []string{} // distinct and sorted usernames
|
||||
|
|
|
@ -5416,6 +5416,12 @@ export default {
|
|||
|
||||
<!-- Who Is Online -->
|
||||
<div v-if="whoTab === 'online'">
|
||||
|
||||
<!-- Show a loading spinner if we are connected but the Who List hasn't arrived -->
|
||||
<div v-if="connected && sortedWhoList.length === 0" class="is-size-7">
|
||||
<i class="fa fa-spinner fa-spin mr-1"></i> Waiting for Who List...
|
||||
</div>
|
||||
|
||||
<div v-for="(u, i) in sortedWhoList" v-bind:key="i">
|
||||
<WhoListRow
|
||||
:user="u"
|
||||
|
|
Loading…
Reference in New Issue
Block a user