1
0
Fork 0

Jobs simplified

This commit is contained in:
Gregory Eremin 2015-03-05 02:08:36 +07:00
parent 9bb84d27b7
commit 3216f261c3
5 changed files with 111 additions and 36 deletions

View File

@ -7,9 +7,9 @@ import (
type ( type (
Job struct { Job struct {
Name string Name string
actor func() actor func(Task)
workers map[string]*worker workers map[string]*worker
orders chan order tasks chan Task
wg sync.WaitGroup wg sync.WaitGroup
} }
) )
@ -19,28 +19,41 @@ func New(name string, actor func()) *Job {
Name: name, Name: name,
actor: actor, actor: actor,
workers: make(map[string]*worker), workers: make(map[string]*worker),
orders: make(chan order), tasks: make(chan Task),
} }
} }
func (j *Job) Workers(n int) { func (j *Job) Perform(t Task) {
j.tasks <- t
}
func (j *Job) Size() int {
return len(j.workers)
}
func (j *Job) Stop() {
j.Resize(0)
j.wg.Wait()
}
func (j *Job) Resize(n int) {
if n < 0 { if n < 0 {
n = 0 n = 0
} }
if del := n - len(j.workers); del > 0 { if del := n - len(j.workers); del > 0 {
for i := 0; i < del; i++ { for i := 0; i < del; i++ {
w := &worker{ w := &worker{
id: newID(), id: newID(),
job: j.Name, job: j,
wg: j.wg, shutdown: make(<-chan struct{}, 1),
actor: j.actor,
} }
go w.workHard() go w.workHard()
j.workers[w.id] = w
} }
j.wg.Add(del) j.wg.Add(del)
} else { } else {
for i := 0; i > del; i-- { for i := 0; i > del; i-- {
j.orders <- stop j.shutdown <- struct{}{}
} }
} }
} }

View File

@ -4,20 +4,23 @@ import (
"time" "time"
"code.google.com/p/go-uuid/uuid" "code.google.com/p/go-uuid/uuid"
"github.com/fatih/structs"
) )
type ( type (
order byte Task struct{}
report struct { report struct {
duration time.Duration duration time.Duration
success bool err error
} }
) )
const (
stop order = iota
)
func newID() string { func newID() string {
return uuid.New() return uuid.New()
} }
func (t *Task) report(rep report) {
meta := structs.Map(t)
meta["duration"] = rep.duration
meta["error"] = rep.err
}

View File

@ -1,18 +1,14 @@
package job package job
import ( import (
"sync"
"time" "time"
) )
type ( type (
worker struct { worker struct {
id string id string
job string job *Job
wg *sync.WaitGroup shutdown <-chan struct{}
actor func()
reports chan<- report
orders <-chan order
} }
) )
@ -20,28 +16,23 @@ func (w *worker) workHard() {
defer w.wg.Done() defer w.wg.Done()
for { for {
select { select {
case o := <-w.orders: case <-w.shutdown:
switch o { return
case stop: case t := <-w.job.tasks:
return w.perform(t)
default:
panic("Confused")
}
default:
action()
} }
} }
} }
func (w *worker) action() { func (w *worker) perform(t Task) {
start := time.Now() start := time.Now()
defer func() { defer func() {
err := recover() err := recover()
w.reports <- report{ t.report(report{
duration: time.Since(start), duration: time.Since(start),
success: (err == nil), success: err,
} })
}() }()
w.actor() w.job.actor(t)
} }

13
task/common.go Normal file
View File

@ -0,0 +1,13 @@
package task
import (
"code.google.com/p/goauth2/oauth"
"github.com/google/go-github/github"
)
func newGithubClient(token string) *github.Client {
trans := &oauth.Transport{
Token: &oauth.Token{AccessToken: token},
}
return github.NewClient(trans.Client())
}

55
task/sync_contrib.go Normal file
View File

@ -0,0 +1,55 @@
package task
import (
"github.com/google/go-github/github"
"github.com/localhots/steward/db"
"github.com/localhots/steward/job"
)
type (
SyncContribTask struct {
Owner string
Repo string
Token string
job.Task
}
)
func SyncContrib(t SyncContribTask) {
contribs := fetchContrib(newGithubClient(t.Token), t.Owner, t.Repo)
for _, c := range contribs {
db.ImportRepo(c)
}
}
func fetchContrib(client *github.Client, owner, repo string) (res []*db.Contrib) {
contribs, resp, err := client.Repositories.ListContributorsStats(owner, repo)
// c.saveResponseMeta(resp)
if err != nil {
if err.Error() == "EOF" {
// Empty repository, not an actual error
return
}
panic(err)
}
for _, c := range contribs {
for _, week := range c.Weeks {
if *week.Commits == 0 {
continue
}
res = append(res, &db.Contrib{
Week: week.Week.Time.Unix(),
Author: *c.Author.Login,
Owner: owner,
Repo: repo,
Commits: *week.Commits,
Additions: *week.Additions,
Deletions: *week.Deletions,
})
}
}
return
}