func (self *mysqlMessageCache) retrieveOnce(service, username string, since time.Time) (msgs []*rpc.MessageContainer, err error) { self.lock.RLock() defer self.lock.RUnlock() rows, err := self.getMultiMsgStmt.Query(service, username, since.Unix(), time.Now().Unix()) if err != nil { err = fmt.Errorf("Data base error: %v; query multi-msg error", err) return } defer rows.Close() msgs = make([]*rpc.MessageContainer, 0, 128) for rows.Next() { mc := new(rpc.MessageContainer) var data []byte var createTime int64 err = rows.Scan(&mc.Id, &mc.SenderService, &mc.Sender, &createTime, &data) if err != nil { return } mc.Message = new(rpc.Message) err = json.Unmarshal(data, mc.Message) if err != nil { return } mc.Birthday = time.Unix(createTime, 0) msgs = append(msgs, mc) } return }
func (self *serverConn) writeDigest(mc *rpc.MessageContainer, extra map[string]string, sz int) error { digest := &proto.Command{ Type: proto.CMD_DIGEST, } params := [4]string{fmt.Sprintf("%v", sz), mc.Id} if mc.FromUser() { params[2] = mc.Sender params[3] = mc.SenderService digest.Params = params[:4] } else { digest.Params = params[:2] } msg := mc.Message header := make(map[string]string, len(extra)+len(msg.Header)) self.digestFielsLock.Lock() defer self.digestFielsLock.Unlock() for _, f := range self.digestFields { if len(msg.Header) > 0 { if v, ok := msg.Header[f]; ok { header[f] = v } } if len(extra) > 0 { if v, ok := extra[f]; ok { header[f] = v } } } if len(header) > 0 { digest.Message = &rpc.Message{ Header: header, } } compress := self.shouldCompress(digest.Message.Size()) return self.cmdio.WriteCommand(digest, compress) }
func (self *mysqlMessageCache) CacheMessage(service, username string, mc *rpc.MessageContainer, ttl time.Duration) (id string, err error) { data, err := json.Marshal(mc.Message) if err != nil { return } if mc.Id == "" { id = randomId() mc.Id = id } else { id = mc.Id } uniqid := getUniqMessageId(service, username, id) if len(uniqid) > maxMessageIdLength { err = fmt.Errorf("message id length is greater than %v characters", maxMessageIdLength) return } if len(username) > maxUsernameLength { err = fmt.Errorf("user %v's name is too long", username) return } if len(mc.Sender) > maxUsernameLength { err = fmt.Errorf("user %v's name is too long", mc.Sender) return } if len(service) > maxServicenameLength { err = fmt.Errorf("service %v's name is too long", service) return } if len(mc.SenderService) > maxServicenameLength { err = fmt.Errorf("service %v's name is too long", mc.SenderService) return } now := time.Now() mc.Birthday = now deadline := now.Add(ttl) if ttl < 1*time.Second { // max possible value for int64 deadline = time.Unix(0, 0) } var result sql.Result err = self.expBackoffRetry(3, 2, func() error { result, err = self.cacheStmt.Exec(uniqid, id, service, username, mc.SenderService, mc.Sender, now.Unix(), deadline.Unix(), data) return err }) if err != nil { err = fmt.Errorf("Data base error: %v; insert error", err) return } n, err := result.RowsAffected() if err != nil { return } if n != 1 { err = fmt.Errorf("affected %v rows, which is weird", n) return } return }