fix(webhook): order matching webhooks by id for deterministic fan-out
Previously WebhookListener.Handle fetched matching webhooks with Find(&ws) without an explicit ORDER BY, so iteration order depended on the DB driver. Add ORDER BY id ASC so the fan-out order is stable for both project- and user-level webhooks, and update the sibling-blocking regression test to insert webhooks with explicit ids so its ordering assumption is robust to autoincrement state.
This commit is contained in:
parent
85a3b3e469
commit
ca7f82a5e5
|
|
@ -69,15 +69,18 @@ func TestWebhookFailingSiblingDoesNotBlockOthers(t *testing.T) {
|
||||||
defer bad.Close()
|
defer bad.Close()
|
||||||
|
|
||||||
// Clean slate + insert two webhooks listening on task.updated for project 1.
|
// Clean slate + insert two webhooks listening on task.updated for project 1.
|
||||||
// Insert bad FIRST so it has the lower id and would be iterated before good.
|
// Use explicit ids so the bad webhook (id=10) is strictly ordered before
|
||||||
// Delete the fixture webhook id=1 (example.com target) first so it
|
// the good one (id=11) once WebhookListener.Handle applies its ORDER BY id.
|
||||||
// does not pollute this test with unrelated delivery failures.
|
// This makes the test independent of auto-increment state and DB insert
|
||||||
|
// ordering. Delete the fixture webhook id=1 (example.com target) first so
|
||||||
|
// it does not pollute this test with unrelated delivery failures.
|
||||||
require.NoError(t, db.LoadFixtures())
|
require.NoError(t, db.LoadFixtures())
|
||||||
s := db.NewSession()
|
s := db.NewSession()
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
_, err = s.Where("id = ?", 1).Delete(&models.Webhook{})
|
_, err = s.Where("id = ?", 1).Delete(&models.Webhook{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = s.Insert(&models.Webhook{
|
_, err = s.Insert(&models.Webhook{
|
||||||
|
ID: 10,
|
||||||
TargetURL: bad.URL,
|
TargetURL: bad.URL,
|
||||||
Events: []string{"task.updated"},
|
Events: []string{"task.updated"},
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
|
|
@ -85,6 +88,7 @@ func TestWebhookFailingSiblingDoesNotBlockOthers(t *testing.T) {
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = s.Insert(&models.Webhook{
|
_, err = s.Insert(&models.Webhook{
|
||||||
|
ID: 11,
|
||||||
TargetURL: good.URL,
|
TargetURL: good.URL,
|
||||||
Events: []string{"task.updated"},
|
Events: []string{"task.updated"},
|
||||||
ProjectID: 1,
|
ProjectID: 1,
|
||||||
|
|
|
||||||
|
|
@ -1121,6 +1121,7 @@ func (wl *WebhookListener) Handle(msg *message.Message) (err error) {
|
||||||
|
|
||||||
ws := []*Webhook{}
|
ws := []*Webhook{}
|
||||||
err = s.In("project_id", projectIDs).
|
err = s.In("project_id", projectIDs).
|
||||||
|
OrderBy("id ASC").
|
||||||
Find(&ws)
|
Find(&ws)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -1142,6 +1143,7 @@ func (wl *WebhookListener) Handle(msg *message.Message) (err error) {
|
||||||
if userID > 0 {
|
if userID > 0 {
|
||||||
userWebhooks := []*Webhook{}
|
userWebhooks := []*Webhook{}
|
||||||
err = s.Where("user_id = ? AND (project_id IS NULL OR project_id = 0)", userID).
|
err = s.Where("user_id = ? AND (project_id IS NULL OR project_id = 0)", userID).
|
||||||
|
OrderBy("id ASC").
|
||||||
Find(&userWebhooks)
|
Find(&userWebhooks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue