-
Notifications
You must be signed in to change notification settings - Fork 7
Status table to add possibility to use those data for progress chart #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0fad366
c376fb1
2c2d8c9
42c2577
725187e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,14 @@ | ||
| package subcmd | ||
|
|
||
| import ( | ||
| "database/sql" | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| "github.com/src-d/ghsync/shallow" | ||
|
|
||
| "gopkg.in/src-d/go-cli.v0" | ||
| "gopkg.in/src-d/go-log.v1" | ||
| ) | ||
|
|
||
| type ShallowCommand struct { | ||
|
|
@@ -29,8 +32,13 @@ func (c *ShallowCommand) Execute(args []string) error { | |
| return err | ||
| } | ||
|
|
||
| orgSyncer := shallow.NewOrganizationSyncer(db, client) | ||
| for _, o := range strings.Split(c.Orgs, ",") { | ||
| orgs := strings.Split(c.Orgs, ",") | ||
| if err = c.initStatus(db, statusTableName, orgs); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| orgSyncer := shallow.NewOrganizationSyncer(db, client, statusTableName) | ||
| for _, o := range orgs { | ||
| err = orgSyncer.Sync(o) | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -39,3 +47,25 @@ func (c *ShallowCommand) Execute(args []string) error { | |
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (c *ShallowCommand) initStatus(db *sql.DB, tableName string, orgs []string) error { | ||
| log.Debugf("initializing status table for orgs: %v", orgs) | ||
| var b strings.Builder | ||
|
|
||
| for _, o := range orgs[:len(orgs)-1] { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whoooh. kallax would make it much better |
||
| b.WriteString(fmt.Sprintf("('%s', 'repository'),", o)) | ||
| b.WriteString(fmt.Sprintf("('%s', 'user'),", o)) | ||
| } | ||
| b.WriteString(fmt.Sprintf("('%s', 'repository'),", orgs[len(orgs)-1])) | ||
| b.WriteString(fmt.Sprintf("('%s', 'user')", orgs[len(orgs)-1])) | ||
|
|
||
| stm := fmt.Sprintf("INSERT INTO %s (org, entity) VALUES %s ON CONFLICT (org, entity) DO UPDATE SET failed=0, done=0, total=NULL;", tableName, b.String()) | ||
| log.Debugf("running statement: %s", stm) | ||
| _, err := db.Exec(stm) | ||
| if err != nil { | ||
| return fmt.Errorf(fmt.Sprintf( | ||
| "an error occured while initializing %s table: %v", tableName, err)) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,16 +13,18 @@ import ( | |
| ) | ||
|
|
||
| type RepositorySyncer struct { | ||
| db *sql.DB | ||
| store *models.RepositoryStore | ||
| client *github.Client | ||
| db *sql.DB | ||
| store *models.RepositoryStore | ||
| client *github.Client | ||
| statusTableName string | ||
| } | ||
|
|
||
| func NewRepositorySyncer(db *sql.DB, c *github.Client) *RepositorySyncer { | ||
| func NewRepositorySyncer(db *sql.DB, c *github.Client, statusTableName string) *RepositorySyncer { | ||
| return &RepositorySyncer{ | ||
| db: db, | ||
| store: models.NewRepositoryStore(db), | ||
| client: c, | ||
| db: db, | ||
| store: models.NewRepositoryStore(db), | ||
| client: c, | ||
| statusTableName: statusTableName, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -52,10 +54,30 @@ func (s *RepositorySyncer) Sync(owner string, logger log.Logger) error { | |
| opts.Page = r.NextPage | ||
| } | ||
|
|
||
| stm := fmt.Sprintf("UPDATE %s SET total=%d WHERE org='%s' AND entity='repository'", | ||
| s.statusTableName, len(repos), owner) | ||
| log.Debugf("running statement: %s", stm) | ||
| if _, err := s.db.Exec(stm); err != nil { | ||
| return fmt.Errorf("an error occured while updating %s table: %v", | ||
| s.statusTableName, err) | ||
| } | ||
|
|
||
| // Process each one of them | ||
| for _, repository := range repos { | ||
| err := s.doRepo(repository, logger) | ||
| if err != nil { | ||
| stm := fmt.Sprintf("UPDATE %s SET failed=failed + 1 WHERE org='%s' AND entity='repository'", | ||
| s.statusTableName, owner) | ||
| if err = s.updateStatus(stm); err != nil { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imo it would be better if we'd count the success/fail, and then update the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But you would lose the possibility to have a pseudo-real-time status chart then, don't you? In case of a sync that requires a lot of time, I think that it's really useful to have it instead of having a report of what happened just in the end.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. real time is great, but with current implementation we're stopping the process if one import or status update fails.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, but if it fails after 1h as I user I could be interested during that hour about the progress. Maybe as a user having 100 of repos once it finishes 50 repos I may want to start doing some charts, and if update just in the end I won't be able to do that.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imo better keep as it is now and maybe change exiting on an error
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yup, I also prefer to keep it as-is because in the short?/mid?/-term IMO we should change the behaviour of exiting at first error. |
||
| return err | ||
| } | ||
|
|
||
| return err | ||
| } | ||
|
|
||
| stm := fmt.Sprintf("UPDATE %s SET done=done + 1 WHERE org='%s' AND entity='repository'", | ||
| s.statusTableName, owner) | ||
| if err = s.updateStatus(stm); err != nil { | ||
| return err | ||
| } | ||
| } | ||
|
|
@@ -65,6 +87,16 @@ func (s *RepositorySyncer) Sync(owner string, logger log.Logger) error { | |
| return nil | ||
| } | ||
|
|
||
| func (s *RepositorySyncer) updateStatus(stm string) error { | ||
| log.Debugf("running statement: %s", stm) | ||
| if _, err := s.db.Exec(stm); err != nil { | ||
| return fmt.Errorf("an error occured while updating %s table: %v", | ||
| s.statusTableName, err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (s *RepositorySyncer) doRepo(repository *github.Repository, parentLogger log.Logger) error { | ||
| logger := parentLogger.With(log.Fields{"repository": repository.GetName()}) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoooh. Why don't use kallax for this table as well?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😂
BTW, have a look here. I actually wanted to use kallax, but given the deadline and that I'm completely new to kallax we agreed with @carlosms to just use raw sql instead. But I personally +1 on using kallax, please let me know if you consider it as a blocker, otherwise I'll open an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay. I tried to add a new model and re-generate code with it using instruction in readme but it didn't work. So just an issue would be fine for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, just to verify that I understood correctly. So after this PR we won't be able to create new models right? Until we also handle this with kallax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. I tried to create a model from master. I mean apparently, it's not that easy to change the current code to use kallax so I'm ok with merging it as it is now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok and thanks for giving it a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened issue.