// handle one request, errors that are returned are deemed fatal and should cause the // connection to be closed func handleRequest(receiver libchan.Receiver) error { // receive a request var req gears.Request err := receiver.Receive(&req) if err != nil { return err } glog.V(2).Infof("Recv: %+v", req) // check that we have a reply channel, if it's missing we treat this as a fatal // error in order to signal to the client that something is very wrong here if req.Reply == nil { return fmt.Errorf("request is missing reply channel") } var rep gears.Reply switch { case req.ER != nil: rep = HandleEchoRequest(req.ER) case req.RFS != nil: rep = HandleRFSubRequest(req.RFS) case req.RF != nil: rep = HandleRFSendRequest(req.RF) case req.SI != nil: rep = HandleSensorInfoRequest(req.SI) case req.SD != nil: rep = HandleSensorDataRequest(req.SD) case req.SR != nil: rep = HandleSensorReadRequest(req.SR) case req.SS != nil: rep = HandleSensorSubRequest(req.SS) case req.PP != nil: rep = HandleParamPutRequest(req.PP) case req.PG != nil: rep = HandleParamGetRequest(req.PG) default: rep = gears.Reply{ Code: gears.CodeClientError, Error: fmt.Sprintf("unknown request: %+v", req), } } err = req.Reply.Send(rep) if err != nil { return fmt.Errorf("cannot send reply: %s", err.Error()) } if rep.Code != gears.CodeOK { // we don't return an error 'cause this is not fatal and we don't // want to close the connection (maybe we should for CodeServerError) // but we can also leave that decision up to the client and thereby // avoid killing pipelined incoming requests glog.Infof("Request handler error: %s", rep.Error) } return nil }
// receive receives new storagedriver.StorageDriver method requests and creates a new goroutine to // handle each request // Requests are expected to be of type ipc.Request as the parameters are unknown until the request // type is deserialized func receive(driver storagedriver.StorageDriver, receiver libchan.Receiver) { for { var request Request err := receiver.Receive(&request) if err == io.EOF { return } else if err != nil { panic(err) } go handleRequest(driver, request) } }
func ReceiveEvents(ch chan FileEvent, receiver libchan.Receiver) error { for { event := &FileEvent{} err := receiver.Receive(event) if err != nil { return err } else { ch <- *event } } return nil }
// receiveResponse populates the response value with the next result from the // given receiver, or returns an error if receiving failed or the driver has // stopped func (driver *StorageDriverClient) receiveResponse(receiver libchan.Receiver, response interface{}) error { receiveChan := make(chan error, 1) go func(receiver libchan.Receiver, receiveChan chan<- error) { receiveChan <- receiver.Receive(response) }(receiver, receiveChan) var err error var ok bool select { case err = <-receiveChan: case err, ok = <-driver.exitChan: if !ok { err = driver.exitErr } } return err }
func (adapter *thingeyAdapter) Listen(receiver libchan.Receiver) error { request := &Request{} response := &Response{} err := receiver.Receive(request) if err != nil { log.Print(err) return err } switch request.Type { case "ThingeyCreateRequest": payload := &ThingeyCreateRequest{} if err = json.Unmarshal(request.Payload, payload); err != nil { return err } adapter.thingeys[payload.Thingey.ID] = payload.Thingey response.Payload, err = json.Marshal(&ThingeyCreateResponse{}) response.Type = "ThingeyCreateResponse" if err != nil { return err } case "ThingeyDeleteRequest": payload := &ThingeyDeleteRequest{} if err = json.Unmarshal(request.Payload, payload); err != nil { return err } delete(adapter.thingeys, payload.Thingey.ID) response.Payload, err = json.Marshal(&ThingeyDeleteResponse{}) response.Type = "ThingeyDeleteResponse" if err != nil { return err } case "ThingeyGetRequest": payload := &ThingeyGetRequest{} if err = json.Unmarshal(request.Payload, payload); err != nil { return err } resp := &ThingeyGetResponse{ Thingey: adapter.thingeys[payload.ThingeyID], } response.Payload, err = json.Marshal(resp) response.Type = "ThingeyGetResponse" if err != nil { return err } case "ThingeyListRequest": payload := &ThingeyListRequest{} if err = json.Unmarshal(request.Payload, payload); err != nil { return err } thingeys := []*Thingey{} for _, t := range adapter.thingeys { thingeys = append(thingeys, t) } resp := &ThingeyListResponse{ Thingeys: thingeys, } response.Payload, err = json.Marshal(resp) response.Type = "ThingeyListResponse" if err != nil { return err } default: response.Err = errors.New("unknown request type") } return request.ResponseChan.Send(response) }