Closed Bug 1385408 Opened 7 years ago Closed 6 years ago

BEGIN EXCLUSIVE failed. Error code: 0 -- Non-open connection

Categories

(Firefox for iOS :: Data Storage, defect, P3)

Other
iOS
defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: justindarc, Assigned: justindarc)

References

Details

(Whiteboard: [MobileCore][DataLoss])

Attachments

(2 files)

Attached file Example Stacktrace
The following message is being logged in Sentry:

BEGIN EXCLUSIVE failed. Error code: 0, Error Domain=mozilla Code=0 "Non-open connection; can't execute change." UserInfo={NSLocalizedDescription=Non-open connection; can't execute change.}

This error seems to occur most often when the app goes to background and tries to get a transaction (`BEGIN EXCLUSIVE`) on a closed DB. We need to properly coordinate access to the database to prevent this.
Assignee: nobody → jdarcangelo
Status: NEW → ASSIGNED
Priority: -- → P1
Whiteboard: [MobileCore][DataLoss]
See Also: → 1368719
This isn't about DB coordination, I think.

That particular stack is: we're finishing a background sync, and when we're done we close the DB (and surrender the background task). Then the AS highlights listener fires. It should not be separate from the background task; AS work should be done in the same place as our top sites cache invalidation.

In general, though, it's always possible for a write to be queued and end up running after the DB has been closed. We can simplify this flow by short-circuiting for a closed connection, but the only way we can truly fix this is to close the DB later, at the end of a background operation range. We probably don't want to do that.

In short: there are ways we can make this situation better, but this is not a cause of data loss.
Summary: [DataLoss] BEGIN EXCLUSIVE failed. Error code: 0 -- Non-open connection → BEGIN EXCLUSIVE failed. Error code: 0 -- Non-open connection
Attached file Log.
Here's a log of me turning off my iPhone. You can see that we stop timed syncs, run a sync-on-exit, close the profile… and then we fail to hit the DB.

Xcode tells me the stack is:

#0	0x000000010237b848 in BrowserDB.withConnection<A> (inout NSError?, callback : (SQLiteDBConnection, inout NSError?) -> A) -> A at /Users/rnewman/moz/git/s2fxios/Storage/SQL/BrowserDB.swift:315
#1	0x0000000102283504 in SQLiteRemoteClientsAndTabs.getClients() -> Deferred<Maybe<[RemoteClient]>> at /Users/rnewman/moz/git/s2fxios/Storage/SQL/SQLiteRemoteClientsAndTabs.swift:158
#2	0x000000010228b9c8 in protocol witness for RemoteClientsAndTabs.getClients() -> Deferred<Maybe<[RemoteClient]>> in conformance SQLiteRemoteClientsAndTabs ()
#3	0x0000000102c4dec8 in static SyncPing.connectedDevices(fromStorage : RemoteClientsAndTabs, token : TokenServerToken) -> Deferred<Maybe<[[String : Any]]>> at /Users/rnewman/moz/git/s2fxios/Sync/SyncTelemetry.swift:324
#4	0x0000000102c4d870 in static SyncPing.dictionaryFrom(result : (engineResults : Maybe<[(String, SyncStatus)]>, stats : SyncOperationStatsSession?), storage : RemoteClientsAndTabs, token : TokenServerToken) -> Deferred<Maybe<[String : Any]>> at /Users/rnewman/moz/git/s2fxios/Sync/SyncTelemetry.swift:280
#5	0x0000000102c4cf38 in static SyncPing.(from(result : (engineResults : Maybe<[(String, SyncStatus)]>, stats : SyncOperationStatsSession?), account : FirefoxAccount, remoteClientsAndTabs : RemoteClientsAndTabs, prefs : Prefs, why : SyncPingReason) -> Deferred<Maybe<SyncPing>>).(closure #1) at /Users/rnewman/moz/git/s2fxios/Sync/SyncTelemetry.swift:268

Which is very likely because of this:

            self.doInBackgroundAfter(300) {
                self.profile.remoteClientsAndTabs.getClientGUIDs() >>== { clients in
                    // We would love to include the version and OS etc. of each remote client,
                    // but we don't store that information. For now, just do a count.
                    let clientCount = clients.count

                    let id = DeviceInfo.clientIdentifier(self.prefs)
                    let ping = makeAdHocBookmarkMergePing(Bundle.main, clientID: id, attempt: attempt, bufferRows: bufferRows, valid: validations, clientCount: clientCount)


… that is: we run a sync on exit, validate bookmarks, close the profile, and then 300msec later we try to build a SyncPing… which needs to look at the clients DB.
Attachment #8893049 - Attachment mime type: text/x-log → text/plain
This is an assigned P1 bug without activity in two weeks. 

If you intend to continue working on this bug for the current release/iteration/sprint, remove the 'stale-bug' keyword.

Otherwise we'll reset the priority of the bug back to '--' on Monday, August 28th.
Keywords: stale-bug
Keywords: stale-bug
Priority: P1 → --
Priority: -- → P3
Closing as we haven't seen this error in quite a while.
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: