func (p *ProtocolV2) REQ(client *ClientV2, params [][]byte) ([]byte, error) { state := atomic.LoadInt32(&client.State) if state != nsq.StateSubscribed && state != nsq.StateClosing { return nil, util.NewFatalClientErr(nil, "E_INVALID", "cannot REQ in current state") } if len(params) < 3 { return nil, util.NewFatalClientErr(nil, "E_INVALID", "REQ insufficient number of params") } id := *(*nsq.MessageID)(unsafe.Pointer(¶ms[1][0])) timeoutMs, err := util.ByteToBase10(params[2]) if err != nil { return nil, util.NewFatalClientErr(err, "E_INVALID", fmt.Sprintf("REQ could not parse timeout %s", params[2])) } timeoutDuration := time.Duration(timeoutMs) * time.Millisecond if timeoutDuration < 0 || timeoutDuration > maxTimeout { return nil, util.NewFatalClientErr(nil, "E_INVALID", fmt.Sprintf("REQ timeout %d out of range 0-%d", timeoutDuration, maxTimeout)) } err = client.Channel.RequeueMessage(client.ID, id, timeoutDuration) if err != nil { return nil, util.NewClientErr(err, "E_REQ_FAILED", fmt.Sprintf("REQ %s failed %s", id, err.Error())) } client.RequeuedMessage() return nil, nil }
func (p *ProtocolV2) RDY(client *ClientV2, params [][]byte) ([]byte, error) { state := atomic.LoadInt32(&client.State) if state == nsq.StateClosing { // just ignore ready changes on a closing channel log.Printf("PROTOCOL(V2): [%s] ignoring RDY after CLS in state ClientStateV2Closing", client) return nil, nil } if state != nsq.StateSubscribed { return nil, util.NewFatalClientErr(nil, "E_INVALID", "cannot RDY in current state") } count := int64(1) if len(params) > 1 { b10, err := util.ByteToBase10(params[1]) if err != nil { return nil, util.NewFatalClientErr(err, "E_INVALID", fmt.Sprintf("RDY could not parse count %s", params[1])) } count = int64(b10) } if count < 0 || count > p.context.nsqd.options.maxRdyCount { // this needs to be a fatal error otherwise clients would have // inconsistent state return nil, util.NewFatalClientErr(nil, "E_INVALID", fmt.Sprintf("RDY count %d out of range 0-%d", count, p.context.nsqd.options.maxRdyCount)) } client.SetReadyCount(count) return nil, nil }