MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / ExpireApproveAndSend

Method ExpireApproveAndSend

internal/identity/store.go:2046–2200  ·  view source on GitHub ↗

ExpireApproveAndSend is the worker-side counterpart to ApproveAndSend: no user ownership check (the caller is the expiration worker, which is system-scoped), SELECT ... FOR NO KEY UPDATE SKIP LOCKED so concurrent workers don't race for the same row, and the terminal status is 'review_expired_approve

(
	ctx context.Context,
	messageID string,
	send func(msg *Message) (SendResult, error),
)

Source from the content-addressed store, hash-verified

2044// ErrNotPendingApproval — skip silently and let the next poll handle
2045// it.
2046func (s *Store) ExpireApproveAndSend(
2047 ctx context.Context,
2048 messageID string,
2049 send func(msg *Message) (SendResult, error),
2050) (*Message, error) {
2051 txCtx, cancel := context.WithTimeout(ctx, approvalTxTimeout)
2052 defer cancel()
2053
2054 tx, err := s.pool.Begin(txCtx)
2055 if err != nil {
2056 return nil, err
2057 }
2058 committed := false
2059 defer func() {
2060 if !committed {
2061 _ = tx.Rollback(txCtx)
2062 }
2063 }()
2064
2065 var (
2066 m Message
2067 bodyText, bodyHTML *string
2068 attachments []byte
2069 method, msgType *string
2070 approvalExpires *time.Time
2071 )
2072 err = tx.QueryRow(txCtx,
2073 `SELECT id, agent_id, direction, sender, recipient, subject,
2074 email_message_id,
2075 method, message_type,
2076 conversation_id, created_at, expires_at,
2077 to_recipients, cc, bcc,
2078 status, approval_expires_at, edited,
2079 body_text, body_html, attachments_json
2080 FROM messages
2081 WHERE id = $1
2082 AND direction = 'outbound'
2083 AND status = 'pending_review'
2084 AND approval_expires_at < now()
2085 FOR NO KEY UPDATE SKIP LOCKED`,
2086 messageID,
2087 ).Scan(
2088 &m.ID, &m.AgentID, &m.Direction, &m.Sender, &m.Recipient, &m.Subject,
2089 &m.EmailMessageID,
2090 &method, &msgType,
2091 &m.ConversationID, &m.CreatedAt, &m.ExpiresAt,
2092 &m.ToRecipients, &m.CC, &m.BCC,
2093 &m.Status, &approvalExpires, &m.Edited,
2094 &bodyText, &bodyHTML, &attachments,
2095 )
2096 if err != nil {
2097 // Row is either gone, no longer pending, not yet expired, or is
2098 // currently locked by another worker. Any of those means "someone
2099 // else will handle it, or nothing to do" — don't bubble as an error.
2100 return nil, ErrNotPendingApproval
2101 }
2102 if method != nil {
2103 m.Method = *method

Implementers 1

Storeinternal/identity/store.go

Calls 12

ClaimSendAttemptMethod · 0.95
MarkSendFailedMethod · 0.95
sendFunction · 0.85
firstOrFunction · 0.85
nullIfEmptyBytesFunction · 0.85
RollbackMethod · 0.80
ScanMethod · 0.80
QueryRowMethod · 0.80
CommitMethod · 0.80
ExecMethod · 0.65
ErrorMethod · 0.45