Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • Q quickfix
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 48
    • Issues 48
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 25
    • Merge requests 25
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • quickfixgo
  • quickfix
  • Issues
  • #447
Closed
Open
Issue created Jul 05, 2021 by Administrator@rootContributor

Persist can cause store to get into inconsistent state

Created by: imirkin

Let's say that one is using the sql store. Persist looks like this:

func (s *session) persist(seqNum int, msgBytes []byte) error {
        if !s.DisableMessagePersist {
                if err := s.store.SaveMessage(seqNum, msgBytes); err != nil {
                        return err
                }
        }

        return s.store.IncrNextSenderMsgSeqNum()
}

So it will save the message to the messages table, and after that, update the outgoing seqnum in the sessions table.

However if the process is terminated in the middle (or there's a database error), you can end up with the message in the messages table, but the outgoing seqnum will still be the old one in the sessions table. Ideally there'd be some transactionality here, but the interfaces don't have anything like that.

This causes problems when the process is restarted and tries to send a message. It will insert another message into the messages table, which will fail due to a primary key constraint.

I believe a reasonable solution would be to flip those two around. In the failure case outlined, you'll just have burned a seqnum, which seems like a reasonable thing to do in such an exceptional situation.

Assignee
Assign to
Time tracking