processInfo is used to parse the info messages sent from the server. This function may update the server pool.
(info string)
| 4047 | // from the server. |
| 4048 | // This function may update the server pool. |
| 4049 | func (nc *Conn) processInfo(info string) error { |
| 4050 | if info == _EMPTY_ { |
| 4051 | return nil |
| 4052 | } |
| 4053 | var ncInfo ServerInfo |
| 4054 | if err := json.Unmarshal([]byte(info), &ncInfo); err != nil { |
| 4055 | return err |
| 4056 | } |
| 4057 | |
| 4058 | // Copy content into connection's info structure. |
| 4059 | nc.info = ncInfo |
| 4060 | // The array could be empty/not present on initial connect, |
| 4061 | // if advertise is disabled on that server, or servers that |
| 4062 | // did not include themselves in the async INFO protocol. |
| 4063 | // If empty, do not remove the implicit servers from the pool. |
| 4064 | if len(nc.info.ConnectURLs) == 0 || nc.Opts.IgnoreDiscoveredServers { |
| 4065 | if !nc.initc && ncInfo.LameDuckMode && nc.Opts.LameDuckModeHandler != nil { |
| 4066 | nc.ach.push(func() { nc.Opts.LameDuckModeHandler(nc) }) |
| 4067 | } |
| 4068 | return nil |
| 4069 | } |
| 4070 | // Note about pool randomization: when the pool was first created, |
| 4071 | // it was randomized (if allowed). We keep the order the same (removing |
| 4072 | // implicit servers that are no longer sent to us). New URLs are sent |
| 4073 | // to us in no specific order so don't need extra randomization. |
| 4074 | hasNew := false |
| 4075 | // This is what we got from the server we are connected to. |
| 4076 | urls := nc.info.ConnectURLs |
| 4077 | // Transform that to a map for easy lookups |
| 4078 | tmp := make(map[string]struct{}, len(urls)) |
| 4079 | for _, curl := range urls { |
| 4080 | tmp[curl] = struct{}{} |
| 4081 | } |
| 4082 | // Walk the pool and removed the implicit servers that are no longer in the |
| 4083 | // given array/map |
| 4084 | sp := nc.srvPool |
| 4085 | for i := 0; i < len(sp); i++ { |
| 4086 | srv := sp[i] |
| 4087 | curl := srv.URL.Host |
| 4088 | // Check if this URL is in the INFO protocol |
| 4089 | _, inInfo := tmp[curl] |
| 4090 | // Remove from the temp map so that at the end we are left with only |
| 4091 | // new (or restarted) servers that need to be added to the pool. |
| 4092 | delete(tmp, curl) |
| 4093 | // Keep servers that were set through Options, but also the one that |
| 4094 | // we are currently connected to (even if it is a discovered server). |
| 4095 | if !srv.isImplicit || srv.URL == nc.current.URL { |
| 4096 | continue |
| 4097 | } |
| 4098 | if !inInfo { |
| 4099 | // Remove from server pool. Keep current order. |
| 4100 | copy(sp[i:], sp[i+1:]) |
| 4101 | nc.srvPool = sp[:len(sp)-1] |
| 4102 | sp = nc.srvPool |
| 4103 | i-- |
| 4104 | } |
| 4105 | } |
| 4106 | // Figure out if we should save off the current non-IP hostname if we encounter a bare IP. |