realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

Results and objects are not `isFrozen` after calling `freeze()` in a read-only realm

Open joaocolaco opened this issue 3 years ago • 7 comments

Hi.

It seems the #7697 bug resurfaces when freezing a realm opened as read-only. In my case calling freeze() in a realm returns exactly the same realm (that also returns false to .isFrozen). Changing readOnly to true in the realm configuration makes freeze() work again.

Can this bug be fixed?

@dianaafanador3 has already done an repo test in https://github.com/realm/realm-swift/issues/7697#issuecomment-1178911563_

Originally posted by @joaocolaco in https://github.com/realm/realm-swift/issues/7697#issuecomment-1175366173

Edit with use case from https://github.com/realm/realm-swift/issues/7697#issuecomment-1179015318:

As for the use case freeze is also useful for querying the database in other threads, something that I need to do in my app (due to calls from SwiftUI and Swift async).

This particular database is in the Bundle Resources of the app so it shouldn't never be written. When the first version of the app was made the frozen functionality wasn't available so it was opened as read-only. When .frozen appeared I started to use it, but it didn't cross my mind that it would interfere with the read-only configuration until now.

Can I make a feature suggestion? Why not make all the read-only realms frozen? That would give "free" functionality and remove this sort of confusions.

joaocolaco avatar Jul 08 '22 14:07 joaocolaco

@tgoyne I don't know if this is the intended behaviour for a read only realm, and the use case is to be able to use the realm in another thread. I have the following test, which reproduce the issue,

func testFreezeReadOnlyRealm() throws {
        try autoreleasepool {
            let realm = try Realm()
            let frozenRealm = realm.freeze()
            XCTAssert(frozenRealm.isFrozen)
        }
        var configuration = Realm.Configuration.defaultConfiguration
        configuration.readOnly = true
        let realm = try Realm(configuration: configuration)
        let frozenRealm = realm.freeze()
        XCTAssert(frozenRealm.isFrozen) // This is failing
    }

Seems like the realm cannot be freeze because it doesn't have a version, but I don't know the intended behaviour behind it.

dianaafanador3 avatar Jul 08 '22 14:07 dianaafanador3

Read-only Realms should probably always just report isFrozen since they behave like frozen Realms and if we did that they'd become safe to use across threads.

tgoyne avatar Jul 11 '22 23:07 tgoyne

And that would also simplify a bit of my code (and whoever uses this functionality).

joaocolaco avatar Jul 11 '22 23:07 joaocolaco

What's the workaround for this bug? I don't quite understand but just realized after a day's effort that this is a library bug that I'm also hitting. Thanks

Ah the OP has a typo, readOnly should be false

aehlke avatar Jan 03 '23 22:01 aehlke

@jedelbo I think this will be a quick fix on OS, checking if the realm is readOnly and always return isFrozen true, then it would be safe to use the realm across threads.

dianaafanador3 avatar Jan 04 '23 14:01 dianaafanador3

The workaround stopped working for me: now when I remove readOnly: true, it complains about not being able to create the .lock file inside the Bundle path.

aehlke avatar Jan 30 '23 05:01 aehlke