Skip to content

Commit

Permalink
Set next attempt date and error_count when msgs are errors fixes: #16
Browse files Browse the repository at this point in the history
  • Loading branch information
nicpottier committed Jul 11, 2017
1 parent fac8dc5 commit d7b8798
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
30 changes: 30 additions & 0 deletions backends/rapidpro/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,36 @@ func (ts *MsgTestSuite) TestStatus() {
status = courier.NewStatusUpdateForExternalID(channel, "ext2", courier.MsgSent)
err = ts.b.WriteMsgStatus(status)
ts.Error(err)

// error our msg
now = time.Now().In(time.UTC)
status = courier.NewStatusUpdateForExternalID(channel, "ext1", courier.MsgErrored)
err = ts.b.WriteMsgStatus(status)
ts.NoError(err)
m, err = readMsgFromDB(ts.b, courier.NewMsgID(10000))
ts.NoError(err)
ts.Equal(m.Status_, courier.MsgErrored)
ts.Equal(m.ErrorCount_, 1)
ts.True(m.ModifiedOn_.After(now))
ts.True(m.NextAttempt_.After(now))

// second go
status = courier.NewStatusUpdateForExternalID(channel, "ext1", courier.MsgErrored)
err = ts.b.WriteMsgStatus(status)
ts.NoError(err)
m, err = readMsgFromDB(ts.b, courier.NewMsgID(10000))
ts.NoError(err)
ts.Equal(m.Status_, courier.MsgErrored)
ts.Equal(m.ErrorCount_, 2)

// third go
status = courier.NewStatusUpdateForExternalID(channel, "ext1", courier.MsgErrored)
err = ts.b.WriteMsgStatus(status)
ts.NoError(err)
m, err = readMsgFromDB(ts.b, courier.NewMsgID(10000))
ts.NoError(err)
ts.Equal(m.Status_, courier.MsgFailed)
ts.Equal(m.ErrorCount_, 3)
}

func (ts *MsgTestSuite) TestHealth() {
Expand Down
32 changes: 26 additions & 6 deletions backends/rapidpro/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,40 @@ func checkMsgExists(b *backend, status *courier.MsgStatusUpdate) (err error) {
return err
}

// the craziness below lets us update our status to 'F' and schedule retries without knowing anything about the message
const updateMsgID = `
UPDATE msgs_msg SET status = :status, modified_on = :modified_on WHERE msgs_msg.id IN
(SELECT msgs_msg.id FROM msgs_msg INNER JOIN channels_channel ON (msgs_msg.channel_id = channels_channel.id)
WHERE (msgs_msg.id = :msg_id AND channels_channel.uuid = :channel_uuid)) RETURNING msgs_msg.id
UPDATE msgs_msg SET
status = CASE WHEN :status = 'E' THEN CASE WHEN error_count = 2 THEN 'F' ELSE 'E' END ELSE :status END,
error_count = CASE WHEN :status = 'E' THEN error_count + 1 ELSE error_count END,
next_attempt = CASE WHEN :status = 'E' THEN NOW() + (5 * (error_count+1) * interval '1 minutes') ELSE next_attempt END,
modified_on = :modified_on
WHERE msgs_msg.id IN
(SELECT msgs_msg.id
FROM msgs_msg INNER JOIN channels_channel ON (msgs_msg.channel_id = channels_channel.id)
WHERE (msgs_msg.id = :msg_id AND channels_channel.uuid = :channel_uuid))
RETURNING msgs_msg.id
`

const updateMsgExternalID = `
UPDATE msgs_msg SET status = :status, modified_on = :modified_on WHERE msgs_msg.id IN
(SELECT msgs_msg.id FROM msgs_msg INNER JOIN channels_channel ON (msgs_msg.channel_id = channels_channel.id)
WHERE (msgs_msg.external_id = :external_id AND channels_channel.uuid = :channel_uuid)) RETURNING msgs_msg.id
UPDATE msgs_msg SET
status = CASE WHEN :status = 'E' THEN CASE WHEN error_count = 2 THEN 'F' ELSE 'E' END ELSE :status END,
error_count = CASE WHEN :status = 'E' THEN error_count + 1 ELSE error_count END,
next_attempt = CASE WHEN :status = 'E' THEN NOW() + (5 * (error_count+1) * interval '1 minutes') ELSE next_attempt END,
modified_on = :modified_on
WHERE msgs_msg.id IN
(SELECT msgs_msg.id
FROM msgs_msg INNER JOIN channels_channel ON (msgs_msg.channel_id = channels_channel.id)
WHERE (msgs_msg.external_id = :external_id AND channels_channel.uuid = :channel_uuid))
RETURNING msgs_msg.id
`

// writeMsgStatusToDB writes the passed in msg status to our db
func writeMsgStatusToDB(b *backend, status *DBMsgStatus) error {
var rows *sqlx.Rows
var err error

if status.ID != courier.NilMsgID {
rows, err = b.db.NamedQuery(updateMsgID, status)
} else if status.ExternalID != "" {
Expand Down Expand Up @@ -125,4 +143,6 @@ type DBMsgStatus struct {
ExternalID string `json:"external_id,omitempty" db:"external_id"`
Status courier.MsgStatus `json:"status" db:"status"`
ModifiedOn time.Time `json:"modified_on" db:"modified_on"`
ErrorCount int `json:"error_count" db:"error_count"`
NextAttempt time.Time `json:"next_attempt" db:"next_attempt"`
}

0 comments on commit d7b8798

Please sign in to comment.