// routine to poll user information for a given room at variable intervals func pollTfsRoomUsers(room *tfs.Room, tfsApi *tfs.Api, min time.Duration, max time.Duration, send *chan interface{}, recv *chan interface{}) { delay := min userMap := make(map[string]*tfs.RoomUser) timer := time.NewTimer(delay) defer timer.Stop() for { select { case <-timer.C: delay = delay * 2 if delay > max { delay = max } users, err := tfsApi.GetRoomUsers(room) if err != nil { trace.Log(err) *send <- fmt.Sprintf("users error %d %s", room.Id, err) return } // added newUserMap := make(map[string]*tfs.RoomUser) for _, user := range users.Value { newUserMap[user.User.Id] = user if _, ok := userMap[user.User.Id]; ok { continue } json, err := json.Marshal(user) if err != nil { trace.Log(err) continue } *send <- fmt.Sprintf("users add %d %s %s", user.RoomId, user.User.Id, json) userMap[user.User.Id] = user delay = min } // removed for _, user := range userMap { if _, ok := newUserMap[user.User.Id]; ok { continue } *send <- fmt.Sprintf("users remove %d %s", user.RoomId, user.User.Id) delete(userMap, user.User.Id) delay = min } // changed for id, user := range newUserMap { if newUserMap[id].IsOnline != userMap[id].IsOnline { json, err := json.Marshal(*user) if err != nil { trace.Log(err) continue } userMap[id] = newUserMap[id] *send <- fmt.Sprintf("users change %d %s %s", user.RoomId, user.User.Id, json) delay = min } } timer.Reset(delay) case <-*recv: // quit return } } }