You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
6.0 KiB
219 lines
6.0 KiB
package ugc |
|
|
|
import ( |
|
"fmt" |
|
"time" |
|
|
|
appDao "go-common/app/job/main/tv/dao/app" |
|
ugcmdl "go-common/app/job/main/tv/model/ugc" |
|
arccli "go-common/app/service/main/archive/api" |
|
arcmdl "go-common/app/service/main/archive/model/archive" |
|
"go-common/library/database/sql" |
|
"go-common/library/log" |
|
) |
|
|
|
const ( |
|
_arcRetry = 3 |
|
_apiRetry = 5 |
|
_sleep = 100 * time.Millisecond |
|
) |
|
|
|
// upImportproc always runs to init the uppers |
|
func (s *Service) upImportproc() { |
|
var ( |
|
err error |
|
uppers []*ugcmdl.Upper |
|
) |
|
defer s.waiter.Done() |
|
for { |
|
if s.daoClosed { |
|
log.Info("upImportproc DB closed!") |
|
return |
|
} |
|
// if no more data, we scan per 30s |
|
if uppers, err = s.dao.Import(ctx); err != nil && err != sql.ErrNoRows { |
|
log.Error("upperImport error %v", err) |
|
appDao.PromError("ImportMid:Err") |
|
time.Sleep(time.Duration(s.c.UgcSync.Frequency.ImportFre)) |
|
continue |
|
} |
|
if len(uppers) == 0 && err == sql.ErrNoRows { |
|
log.Info("No Import Data") |
|
time.Sleep(time.Duration(s.c.UgcSync.Frequency.ImportFre)) |
|
continue |
|
} |
|
if err = s.upImport(uppers); err != nil { |
|
log.Error("upImport Error %v", err) |
|
appDao.PromError("ImportMid:Err") |
|
time.Sleep(time.Duration(s.c.UgcSync.Frequency.ImportFre)) |
|
continue |
|
} |
|
appDao.PromInfo("ImportMid:Succ") |
|
time.Sleep(1 * time.Second) |
|
} |
|
} |
|
|
|
// upImport loads 20 uppers to init, and load them one by one |
|
func (s *Service) upImport(uppers []*ugcmdl.Upper) (err error) { |
|
for _, v := range uppers { |
|
// import data |
|
if err = s.InitUpper(v.MID); err != nil { |
|
log.Error("initUpper MID: %v, Err: %v, Postpone the MID", v.MID, err) |
|
s.dao.PpUpper(ctx, v.MID) |
|
continue |
|
} |
|
// update the status |
|
if err = s.dao.FinishUpper(ctx, v.MID); err != nil { |
|
log.Error("FinishUpper Mid: %d, Err: %v", v.MID, err) |
|
return |
|
} |
|
time.Sleep(time.Duration(s.c.UgcSync.Frequency.UpperPause)) // pause after import each upper |
|
} |
|
return |
|
} |
|
|
|
// InitUpper takes the upper's archive & videos, load them into our DB |
|
func (s *Service) InitUpper(mid int64) (err error) { |
|
var ( |
|
arcCount int |
|
ps = s.c.UgcSync.Batch.ArcPS // page size to pick archives |
|
ptn int // total page number |
|
pMatch map[int64]*arccli.Arc // the mapping of aid to archive model of one page |
|
pAids []int64 // the aids of one page |
|
videoNum int64 |
|
begin = time.Now() |
|
) |
|
// count upper's archive and get the total number of pages to get |
|
if arcCount, err = s.arcCount(mid); err != nil { |
|
return |
|
} |
|
log.Info("InitUpper mid %d, Count: %d", mid, arcCount) |
|
if arcCount == 0 { |
|
log.Error("Upper %d Arc Count is 0", mid) |
|
return |
|
} |
|
if arcCount%ps == 0 { |
|
ptn = arcCount / ps |
|
} else { |
|
ptn = arcCount/ps + 1 |
|
} |
|
// get the upper's archives page by page |
|
for i := 1; i <= ptn; i++ { |
|
if pMatch, pAids, err = s.UpArchives(mid, i, ps); err != nil { |
|
log.Error("Mid %d, Page %d Error %v", mid, i, err) |
|
return |
|
} |
|
if len(pMatch) == 0 { // which means this page is all existing |
|
log.Error("Mid %d, Page %d, no need to import Due to Types Hit", mid, i) |
|
continue |
|
} |
|
if err = s.dao.FilterExist(ctx, &pMatch, pAids); err != nil { // filter the existing ones |
|
log.Error("Mid %d, Page %d Error %v", mid, i, err) |
|
return |
|
} |
|
if len(pMatch) == 0 { // which means this page is all existing |
|
log.Error("Mid %d, Page %d, no need to impot Due to Existing", mid, i) |
|
continue |
|
} |
|
if err = s.arcsIn(pMatch); err != nil { // insert this page's arc & views data into our DB |
|
log.Error("Mid %d, Page %d Error %v", mid, i, err) |
|
return |
|
} |
|
videoNum = videoNum + int64(len(pMatch)) |
|
time.Sleep(time.Duration(s.c.UgcSync.Frequency.UpInitFre)) // pause after import each page of upper's archive |
|
} |
|
log.Info("ImportUpper Mid %d, Page Number %d, Page Size %d, "+ |
|
"Video Number %d, Time %v", mid, ptn, ps, videoNum, time.Since(begin)) // record init upper time |
|
return |
|
} |
|
|
|
// get map's keys |
|
func mapKeys(myMap map[int64]*arccli.Arc) (keys []int64) { |
|
for k := range myMap { |
|
keys = append(keys, k) |
|
} |
|
return |
|
} |
|
|
|
// UpArchives picks one page of the up's archives |
|
func (s *Service) UpArchives(mid int64, pn int, ps int) (match map[int64]*arccli.Arc, aids []int64, err error) { |
|
var res []*arccli.Arc |
|
match = make(map[int64]*arccli.Arc) |
|
if err = Retry(func() (err error) { |
|
if res, err = s.arcRPC.UpArcs3(ctx, &arcmdl.ArgUpArcs2{ |
|
Mid: mid, |
|
Pn: pn, |
|
Ps: ps, |
|
}); err != nil { |
|
log.Error("%+v", err) |
|
} |
|
return |
|
}, _arcRetry, _sleep); err != nil { |
|
log.Error("upArchives Error %+v", err) |
|
return |
|
} else if len(res) == 0 { |
|
err = fmt.Errorf("result empty") |
|
return |
|
} |
|
for _, v := range res { |
|
arcAllow := &ugcmdl.ArcAllow{} |
|
arcAllow.FromArcmdl(v) |
|
if allow := s.arcAllowImport(arcAllow); !allow { // check whether the archive is allowed to import into TV db |
|
continue |
|
} |
|
match[v.Aid] = v |
|
aids = append(aids, v.Aid) |
|
} |
|
return |
|
} |
|
|
|
// Retry . retry one function until no error |
|
func Retry(callback func() error, retry int, sleep time.Duration) (err error) { |
|
for i := 0; i < retry; i++ { |
|
if err = callback(); err == nil { |
|
return |
|
} |
|
time.Sleep(sleep) |
|
} |
|
return |
|
} |
|
|
|
// arcsIn picks one page of archive data and their views data, to import them into the DB one by one |
|
func (s *Service) arcsIn(pMatch map[int64]*arccli.Arc) (err error) { |
|
var ( |
|
tx *sql.Tx |
|
pViews map[int64]*arccli.ViewReply |
|
pAids []int64 |
|
) |
|
// get the filtered aids to get the views |
|
pAids = mapKeys(pMatch) |
|
if pViews, err = s.arcViews(pAids); err != nil { |
|
log.Error("arcsIn Error %v", err) |
|
return |
|
} |
|
// import the arc & its video one by one |
|
for aid, arc := range pMatch { |
|
// begin the transaction and insert the archive data |
|
if tx, err = s.dao.BeginTran(ctx); err != nil { // begin transaction |
|
return |
|
} |
|
arc.Pic = s.coverURL(arc.Pic, s.c.UgcSync.Cfg.BFSPrefix) |
|
if err = s.dao.TxImportArc(tx, arc); err != nil { |
|
tx.Rollback() |
|
return |
|
} |
|
cViews, ok := pViews[arc.Aid] |
|
if !ok { |
|
log.Error("arcIn View Data for %d not found", arc.Aid) |
|
tx.Rollback() |
|
return |
|
} |
|
if err = s.dao.TxMnlVideos(tx, cViews); err != nil { |
|
tx.Rollback() |
|
return |
|
} |
|
tx.Commit() |
|
log.Info("Succ Add Arc & View for Aid: %d", aid) |
|
} |
|
return |
|
}
|
|
|