Try to generate multiple uid before failing
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
ddad9371dc
commit
feb59bfab1
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"expvar"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -15,6 +16,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/lib/pq"
|
||||||
"p83.nl/go/ekster/pkg/auth"
|
"p83.nl/go/ekster/pkg/auth"
|
||||||
"p83.nl/go/ekster/pkg/fetch"
|
"p83.nl/go/ekster/pkg/fetch"
|
||||||
"p83.nl/go/ekster/pkg/microsub"
|
"p83.nl/go/ekster/pkg/microsub"
|
||||||
|
@ -26,6 +28,14 @@ import (
|
||||||
"willnorris.com/go/microformats"
|
"willnorris.com/go/microformats"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
varMicrosub *expvar.Map
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
varMicrosub = expvar.NewMap("microsub")
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultPrio is the priority value for new channels
|
// DefaultPrio is the priority value for new channels
|
||||||
const DefaultPrio = 9999999
|
const DefaultPrio = 9999999
|
||||||
|
|
||||||
|
@ -125,27 +135,53 @@ GROUP BY c.id;
|
||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func shouldRetryWithNewUID(err error, try int) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, ok := err.(*pq.Error); ok {
|
||||||
|
if e.Code == "23505" && e.Constraint == "channels_uid_key" {
|
||||||
|
if try > 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ChannelsCreate creates a channels
|
// ChannelsCreate creates a channels
|
||||||
func (b *memoryBackend) ChannelsCreate(name string) (microsub.Channel, error) {
|
func (b *memoryBackend) ChannelsCreate(name string) (microsub.Channel, error) {
|
||||||
uid := util.RandStringBytes(24)
|
varMicrosub.Add("ChannelsCreate", 1)
|
||||||
|
/*
|
||||||
|
* try 5 times to generate a uid for a channel.
|
||||||
|
* If we get a database error we retry.
|
||||||
|
*/
|
||||||
|
try := 0
|
||||||
channel := microsub.Channel{
|
channel := microsub.Channel{
|
||||||
UID: uid,
|
|
||||||
Name: name,
|
Name: name,
|
||||||
Unread: microsub.Unread{Type: microsub.UnreadCount},
|
Unread: microsub.Unread{Type: microsub.UnreadCount},
|
||||||
}
|
}
|
||||||
|
for {
|
||||||
result, err := b.database.Exec(`insert into "channels" ("uid", "name", "created_at") values($1, $2, DEFAULT)`, channel.UID, channel.Name)
|
varMicrosub.Add("ChannelsCreate.RandStringBytes", 1)
|
||||||
if err != nil {
|
channel.UID = util.RandStringBytes(24)
|
||||||
return channel, err
|
result, err := b.database.Exec(`insert into "channels" ("uid", "name", "created_at") values($1, $2, DEFAULT)`, channel.UID, channel.Name)
|
||||||
}
|
if err != nil {
|
||||||
|
log.Println("channels insert", err)
|
||||||
if n, err := result.RowsAffected(); err != nil {
|
if !shouldRetryWithNewUID(err, try) {
|
||||||
if n > 0 {
|
return channel, err
|
||||||
b.broker.Notifier <- sse.Message{Event: "new channel", Object: channelMessage{1, channel}}
|
}
|
||||||
|
try++
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if n, err := result.RowsAffected(); err != nil {
|
||||||
|
if n > 0 {
|
||||||
|
b.broker.Notifier <- sse.Message{Event: "new channel", Object: channelMessage{1, channel}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return channel, nil
|
||||||
}
|
}
|
||||||
return channel, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChannelsUpdate updates a channels
|
// ChannelsUpdate updates a channels
|
||||||
|
|
Loading…
Reference in New Issue
Block a user