Store failed requests in db for later retries

This commit is contained in:
Melody Becker 2025-06-13 13:43:27 +02:00
parent d86ad370df
commit 1c216e415d
Signed by: mstar
SSH key fingerprint: SHA256:9VAo09aaVNTWKzPW7Hq2LW+ox9OdwmTSHRoD4mlz1yI
8 changed files with 1292 additions and 250 deletions

View file

@ -0,0 +1,19 @@
package models
import "regexp"
type FailedOutboundRequestReason string
const (
RequestFailureNotAttemptedYet FailedOutboundRequestReason = "not attempted yet"
RequestFailureUnreachable FailedOutboundRequestReason = "target not reachable"
RequestFailureInternalError FailedOutboundRequestReason = "target internal error"
RequestFailureRejected FailedOutboundRequestReason = "request rejected"
RequestFailureRequestError FailedOutboundRequestReason = "request returned an error"
RequestFailureRateLimitedNoInfo FailedOutboundRequestReason = "request was rate-limited, no rate limit info"
RequestFailureRateLimitTemplate FailedOutboundRequestReason = "request was rate-limited: limit: %d, remaining: %d, reset: %d"
)
var RequestFailureRateLimitRegex = regexp.MustCompile(
`request was rate-limited: limit: ([0-9\-]+), remaining: ([0-9\-]+), reset: ([0-9\-]+)`,
)

View file

@ -0,0 +1,18 @@
package models
import "time"
// Stores an outbound request that hasn't successfully resolved yet
type FailedOutboundRequest struct {
Id uint64 `gorm:"primarykey"`
RawData []byte // The body data of the request
Target string // The url to send the data to (via post)
FirstAttempt time.Time // When the first attempt was started
LastAttempt time.Time // When the latest attempt was started
ActingUser *User // The user on who's behalf the request is being performed
ActingUserId string // Id of the acting user
NrOfAttempts uint32 // How often the request was attempted already
LastFailureReason string // The reason why the last attempt failed (actually a FailedOutboundRequestReason)
TargetServer *RemoteServer // The remote server being targeted. Included to determine if a request still has a chance of success
TargetServerId uint // Id of the target remote server
}

View file

@ -2,6 +2,7 @@ package models
import (
"database/sql"
"time"
"gorm.io/gorm"
)
@ -11,13 +12,15 @@ import (
type RemoteServer struct {
gorm.Model
// The software the server is based on (Mastodon+Glitch => Mastodon, Sharkey => Misskey, Akoma => Plemora, etc)
ServerType ServerSoftwareType
SpecificType string // Specific software name (Sharkey, Iceshrimp, Akoma, etc)
Version string
Domain string // `gorm:"primaryKey"` // Domain the server exists under. Additional primary key
Name string // What the server wants to be known as (usually same as url)
Icon *MediaMetadata // The icon used by the server. May be empty
IconId sql.NullString // ID of a media file
IsSelf bool // Whether this server is yours truly
Metadata []RemoteServerMetadata
ServerType ServerSoftwareType
SpecificType string // Specific software name (Sharkey, Iceshrimp, Akoma, etc)
Version string
Domain string // `gorm:"primaryKey"` // Domain the server exists under. Additional primary key
Name string // What the server wants to be known as (usually same as url)
Icon *MediaMetadata // The icon used by the server. May be empty
IconId sql.NullString // ID of a media file
IsSelf bool // Whether this server is yours truly
Metadata []RemoteServerMetadata // Metadata a server provides in its nodeinfo
LastInteraction time.Time // The last time the server was seen (sucessful outbound request or inbound message)
IsDead bool // Whether to consider a server dead and not bother sending anything anymore
}