func (self *ShardData) forwardRequest(request *p.Request) ([]<-chan *p.Response, []uint32, error) { ids := []uint32{} responses := []<-chan *p.Response{} for _, server := range self.clusterServers { responseChan := make(chan *p.Response, 1) // do this so that a new id will get assigned request.Id = nil log.Debug("Forwarding request %s to %d", request.GetDescription(), server.Id) server.MakeRequest(request, responseChan) responses = append(responses, responseChan) ids = append(ids, server.Id) } return responses, ids, nil }
func (self *ShardData) HandleDestructiveQuery(querySpec *parser.QuerySpec, request *p.Request, response chan<- *p.Response, runLocalOnly bool) { if !self.IsLocal && runLocalOnly { panic("WTF islocal is false and runLocalOnly is true") } responseChannels := []<-chan *p.Response{} serverIds := []uint32{} if self.IsLocal { err := self.deleteDataLocally(querySpec) if err != nil { msg := err.Error() log.Error(msg) response <- &p.Response{ Type: p.Response_ERROR.Enum(), ErrorMessage: &msg, } return } } log.Debug("request %s, runLocalOnly: %v", request.GetDescription(), runLocalOnly) if !runLocalOnly { responses, ids, _ := self.forwardRequest(request) serverIds = append(serverIds, ids...) responseChannels = append(responseChannels, responses...) } var errorResponse *p.Response for idx, channel := range responseChannels { serverId := serverIds[idx] log.Debug("Waiting for response to %s from %d", request.GetDescription(), serverId) for { res := <-channel log.Debug("Received %s response from %d for %s", res.GetType(), serverId, request.GetDescription()) if res.GetType() == p.Response_END_STREAM { break } // don't send the access denied response until the end so the readers don't close out before the other responses. // See https://github.com/Wikia/influxdb/issues/316 for more info. if res.GetType() != p.Response_ERROR { response <- res } else if errorResponse == nil { errorResponse = res } } } if errorResponse != nil { response <- errorResponse return } response <- &p.Response{Type: p.Response_END_STREAM.Enum()} }