func (m *MDb) TPing() { var showlog = ShowLog && (util.Now()-m.log_time > ShowLogTime) if showlog { m.log_time = util.Now() log.D("MDb start ping to %v ", m.String()) } err := m.H.Ping(m.DB) if err == nil || err.Error() != "Closed explicitly" { if err == nil { if showlog { log.D("MDb ping to %v success", m.String()) } } else { log.E("MDb ping to %v error->%v, will mark to not active", m.String(), err) } m.lck.Lock() m.Active = err == nil m.ping = 0 m.lck.Unlock() return } // m.H.Close(m.DB) //do reconnect log.E("MDb ping to %v error->%v, will try reconnect", m.String(), err) for { db, err := m.H.Create() if err == nil { log.D("MDb connect to %v success, will mark to active", m.String()) m.lck.Lock() m.DB = db m.ping = 0 m.Active = true m.lck.Unlock() break } else { log.E("MDb connect to %v error->%v, will retry after 5s", m.String(), err) time.Sleep(5 * time.Second) } } }
func (m *MDbs) SelMDb() *MDb { all := len(m.Dbs) if all < 1 { panic("database session list is empty, please add at last one") } tidx := atomic.AddUint32(&m.onum, 1) bidx := int(tidx % uint32(all)) beg := util.Now() for { for i := 0; i < all; i++ { mdb := m.Dbs[(bidx+i)%all] if mdb.IsActive() { atomic.AddUint64(&mdb.Hited, 1) return mdb } } log.W("MDbs all session is not active, it will retry after 1s") time.Sleep(time.Second) if util.Now()-beg > m.Timeout { break } } panic(fmt.Sprintf("MDbs wait database active timeout(%vms)", m.Timeout)) }
//list task from db func (m *MdbH) List(mid string, running []string, status string, skip, limit int) (int, []*dtm.Task, error) { if len(mid) > 0 { _, err := m.C().UpdateAll( bson.M{ "mid": mid, "_id": bson.M{"$nin": running}, }, bson.M{ "$set": bson.M{"mid": ""}, }) if err != nil { return 0, nil, err } } var and = []bson.M{} and = append(and, bson.M{ "$or": []bson.M{ bson.M{"mid": ""}, bson.M{"mid": bson.M{"$exists": false}}, }, }) and = append(and, bson.M{ "$or": []bson.M{ bson.M{ "next": bson.M{ "$lt": util.Now(), }, }, bson.M{"next": bson.M{"$exists": false}}, }, }) if len(running) > 0 { and = append(and, bson.M{ "_id": bson.M{ "$nin": running, }, }) } if len(status) > 0 { and = append(and, bson.M{ "status": status, }) } var ts []*dtm.Task var err = m.C().Find(bson.M{"$and": and}).Skip(skip).Limit(limit).All(&ts) if err != nil { return 0, nil, err } var rts []*dtm.Task if len(mid) > 0 { for _, t := range ts { _, err = m.C().Find(bson.M{ "$and": []bson.M{ bson.M{"_id": t.Id}, bson.M{"$or": []bson.M{ bson.M{"mid": ""}, bson.M{"mid": bson.M{"$exists": false}}, }}, }, }).Apply(tmgo.Change{ Update: bson.M{ "$set": bson.M{ "mid": mid, }, }, }, nil) if err == nil { rts = append(rts, t) } else if err == tmgo.ErrNotFound { continue } else { return 0, nil, err } } } else { rts = ts } var total int = 0 if err == nil { total, err = m.C().Count() } return total, rts, err }
//update task to db func (m *MdbH) Update(t *dtm.Task) error { t.Time = util.Now() return m.C().Update(bson.M{"_id": t.Id}, t) }
//add task to db func (m *MdbH) Add(t *dtm.Task) error { log.D("MdbH add task by id(%v)", t.Id) t.Time = util.Now() return m.C().Insert(t) }