Skip to content

Commit 3fc6fbf

Browse files
committed
Fix a bug in the app's repo lifecycle.
Previously, the lifecycle of a repo was: validating -> initializing -> hooks initializing -> ready However, the "initialize" method (which corresponds to the "initializing" state) was reused to update the repo in response to any web hooks being called, and this caused it to continuously recreate the web hook (as it thought it needed to transition from the "initializing" to "hooks initializing" state). This change fixes that bug by reordering the lifecycle states so that "hooks initializing" comes *before* "initializing", and so the "initialize" method does not need to do any follow up work other than make sure the repo is in the "ready" state (which is an idempotent operation).
1 parent 41aec20 commit 3fc6fbf

1 file changed

Lines changed: 30 additions & 14 deletions

File tree

app/operations.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,28 @@ func retry(c context.Context, f func() (*github.Response, error)) error {
8282
return errTooManyRetries
8383
}
8484

85-
// Each repository goes through a few operations:
86-
// - validate: ensure the repository is real, accessible with the given token, etc.
87-
// - initialize: initial, pull-everything-into-notes operation (can be
88-
// repeated later - merging notes upstream is indempotent due to
89-
// cat-sort-uniq, even though local notes might have some duplication.)
90-
// - hook: setup web hooks
85+
// Each repository goes through the following lifecycle states:
86+
//
87+
// [validating]
88+
// |
89+
// | (validate access to the repo)
90+
// |
91+
// V
92+
// [hooks initializing]
93+
// |
94+
// | (create the web hook, and then recieve the web hook "ping")
95+
// |
96+
// V
97+
// [initializing]
98+
// |
99+
// | (mirror the pull requests)
100+
// |
101+
// V
102+
// [ready]
103+
// | ^
104+
// | | (recieve any web hook and mirror the pull requests)
105+
// | |
106+
// +-+
91107

92108
// validate ensures that the repo is accessible
93109
func validate(user, repo string) {
@@ -183,15 +199,14 @@ func validate(user, repo string) {
183199
}
184200

185201
err = modifyRepoData(c, user, repo, func(item *repoStorageData) {
186-
item.Status = statusInitializing
202+
item.Status = statusHooksInitializing
187203
})
188204

189205
if err != nil {
190206
errorf("Can't change repo status: %s", err.Error())
191207
}
192208

193-
// Pass of to initialization
194-
initialize(user, repo)
209+
go createHooks(user, repo)
195210
}
196211

197212
// initialize performs initial reading and commiting for the repository
@@ -268,7 +283,7 @@ func initialize(userName, repoName string) {
268283
log.Infof(c, "Success initializing %s/%s", userName, repoName)
269284

270285
err = modifyRepoData(c, userName, repoName, func(item *repoStorageData) {
271-
item.Status = statusHooksInitializing
286+
item.Status = statusReady
272287
})
273288

274289
if err != nil {
@@ -278,8 +293,6 @@ func initialize(userName, repoName string) {
278293
err.Error(),
279294
)
280295
}
281-
282-
go createHooks(userName, repoName)
283296
}
284297

285298
// hook sets up webhooks for a given repository
@@ -456,12 +469,15 @@ func pingHook(userName, repoName string, repoData repoStorageData, content []byt
456469
}
457470

458471
err = modifyRepoData(c, userName, repoName, func(item *repoStorageData) {
459-
item.Status = statusReady
472+
item.Status = statusInitializing
460473
})
461474

462475
if err != nil {
463-
log.Errorf(c, "Can't set repo %s/%s to ready: %s", userName, repoName, err.Error())
476+
log.Errorf(c, "Can't set repo %s/%s to initializing: %s", userName, repoName, err.Error())
464477
}
478+
479+
// Pass of to initialization
480+
go initialize(userName, repoName)
465481
}
466482

467483
// makeErrorf returns a utility function that logs a given error and then sets the repo's error information to that error

0 commit comments

Comments
 (0)