func (pq *PQueue) tsParamFunc(params []string, f func(int64) int64) iface.IResponse { var err *common.ErrorResponse var ts int64 = -1 for len(params) > 0 { switch params[0] { case PRM_TIMESTAMP: params, ts, err = common.ParseInt64Params(params, 0, math.MaxInt64) default: return makeUnknownParamResponse(params[0]) } if err != nil { return err } } if ts < 0 { return common.ERR_TS_PARAMETER_NEEDED } var result int64 = 0 pq.lock.Lock() for { value := f(ts) if value == 0 { break } result += value } pq.lock.Unlock() return common.NewIntResponse(result) }
// Push message to the queue. // Pushing message automatically enables auto expiration. func (pq *PQueue) Push(params []string) iface.IResponse { var err *common.ErrorResponse var msgId string var priority int64 = pq.config.MaxPriority - 1 var payload string = "" for len(params) > 0 { switch params[0] { case PRM_ID: params, msgId, err = common.ParseStringParam(params, 1, 128) case PRM_PRIORITY: params, priority, err = common.ParseInt64Params(params, 0, pq.config.MaxPriority-1) case PRM_PAYLOAD: params, payload, err = common.ParseStringParam(params, 1, 512*1024) default: return makeUnknownParamResponse(params[0]) } if err != nil { return err } } if len(msgId) == 0 { msgId = common.GenRandMsgId() } pq.config.LastPushTs = common.Uts() pq.lock.Lock() defer pq.lock.Unlock() pq.msgSerialNumber += 1 msg := NewPQMessage(msgId, priority, pq.msgSerialNumber) return pq.storeMessage(msg, payload) }
// Pop first available messages. // Will return nil if there are no messages available. func (pq *PQueue) Pop(params []string) iface.IResponse { var err *common.ErrorResponse var limit int64 = 1 lockTimeout := pq.config.PopLockTimeout for len(params) > 0 { p := params[0] switch p { case PRM_LOCK_TIMEOUT: params, lockTimeout, err = common.ParseInt64Params(params, 0, pq.config.PopLockTimeout) case PRM_LIMIT: params, limit, err = common.ParseInt64Params(params, 1, conf.CFG.PQueueConfig.MaxPopBatchSize) default: return makeUnknownParamResponse(params[0]) } if err != nil { return err } } return common.NewItemsResponse(pq.popMessages(lockTimeout, limit)) }
// PopWait pops up to specified number of messages, if there are no available messages. // It will wait until either new message is pushed or wait time exceeded. func (pq *PQueue) PopWait(params []string) iface.IResponse { var err *common.ErrorResponse var limit int64 = 1 var popWaitTimeout int64 = 1000 var lockTimeout int64 = pq.config.PopLockTimeout for len(params) > 0 { switch params[0] { case PRM_LOCK_TIMEOUT: params, lockTimeout, err = common.ParseInt64Params(params, 0, 24*1000*3600) case PRM_LIMIT: params, limit, err = common.ParseInt64Params(params, 1, conf.CFG.PQueueConfig.MaxPopBatchSize) case PRM_POP_WAIT_TIMEOUT: params, popWaitTimeout, err = common.ParseInt64Params(params, 1, conf.CFG.PQueueConfig.MaxPopWaitTimeout) default: return makeUnknownParamResponse(params[0]) } if err != nil { return err } } return common.NewItemsResponse(pq.popWaitItems(lockTimeout, popWaitTimeout, limit)) }
// Set a user defined message lock timeout. Only locked message timeout can be set. func (pq *PQueue) SetLockTimeout(params []string) iface.IResponse { var err *common.ErrorResponse var msgId string var lockTimeout int64 = -1 for len(params) > 0 { switch params[0] { case PRM_ID: params, msgId, err = common.ParseStringParam(params, 1, 128) case PRM_LOCK_TIMEOUT: params, lockTimeout, err = common.ParseInt64Params(params, 0, 24*1000*3600) default: return makeUnknownParamResponse(params[0]) } if err != nil { return err } } if len(msgId) == 0 { return common.ERR_MSG_ID_NOT_DEFINED } if lockTimeout < 0 { return common.ERR_MSG_TIMEOUT_NOT_DEFINED } pq.lock.Lock() defer pq.lock.Unlock() msg, err := pq.unflightMessage(msgId) if err != nil { return err } msg.UnlockTs = common.Uts() + int64(lockTimeout) pq.inFlightHeap.PushItem(msgId, msg.UnlockTs) pq.database.StoreItem(pq.serviceId, msg) return common.OK_RESPONSE }