Closed alecpetrosky closed 4 years ago
Removing all elements from mediumBox before emptying collectionBox, works just fine. So I guest it's the question of cascade delete handling logic.
It makes sense to remove Medium before Collection because the relation data is part of Medium. Thus you delete both things in one go. If you delete the Collection first, it will clear out the relation in all Medium objects additionally. This step is probably what takes most time. It's time wasted as you remove all Medium objects afterwards anyways. We should point that out in the docs, I guess.
However, I see quite a gap between "waiting indefinitely" and "works fine". Thus I'd like to investigate.
How many objects for each type do you have stored at that point?
Do you have some timing data (how long do those removes take)?
Do you happen to have some code to reproduce this?
Thanks!
Couldn't reproduce yet, e.g. with test entities from the repo:
func TestRelationsRemoval(t *testing.T) {
var env = model.NewTestEnv(t)
defer env.Close()
var total = uint64(10000)
var relBox = model.BoxForTestEntityRelated(env.ObjectBox)
var relObject = model.TestEntityRelated{}
relBox.Put(&relObject)
for i := uint64(0); i < total; i++ {
id, err := env.Box.Put(&model.Entity{
Related: relObject,
})
assert.NoErr(t, err)
assert.True(t, id == i+1)
}
count, err := env.Box.Count()
assert.NoErr(t, err)
assert.Eq(t, total, count)
count, err = relBox.Count()
assert.NoErr(t, err)
assert.Eq(t, uint64(1), count)
assert.NoErr(t, relBox.RemoveAll())
empty, err := relBox.IsEmpty()
assert.NoErr(t, err)
assert.True(t, empty)
count, err = env.Box.Count()
assert.NoErr(t, err)
assert.Eq(t, total, count)
assert.NoErr(t, env.Box.RemoveAll())
empty, err = env.Box.IsEmpty()
assert.NoErr(t, err)
assert.True(t, empty)
}
@alecpetrosky could you please post a minimum reproducible example?
@vaind maybe try with 1 M objects?
Hmm, interestingly the issue starts at 10k objects (exactly)...
var count = uint64(9999)
finishes in 200ms, while 10000
goes on "forever" (i stopped it after a couple of seconds).
Hmm, interestingly the issue starts at 10k objects (exactly)...
var count = uint64(9999)
finishes in 200ms, while10000
goes on "forever" (i stopped it after a couple of seconds).
My case was 100k objects. I cancelled it after 5 hours.
1. How many objects for each type do you have stored at that point?
Collection: 2 objects Medium: 100k
2. Do you have some timing data (how long do those removes take)?
RemoveAll Medium, then RemoveAll Collection ~ 1 second, no more. RemoveAll Collection, then RemoveAll Medium - never happens.
Thanks, I've been able to reproduce the issue and the fix is WIP and will come with the next C-API release. Will update this issue once Go is updated to use that c-api version.
In the meantime, one of the workarounds is to remove relation source entities ("Medium" in your example) in smaller batches (less than 10k at once).
Fixed internally. However, not sure when we release this as is located in the C API, which progressed quite a bit (ObjectBox Go has to catch up first). @alecpetrosky Are you good with the "workarounds" for a while? As I've written before, removing Medium before Collection makes more sense anyway in terms of performance.
@greenrobot yes, I'm good with this workaround. The most important thing is that you fixed it so quickly and in some time in the future it'll land in Go. Thank you. Great job!
If in both boxes data present, calling
before
and Objectbox just does something unknown indefinitely until interrupted. No errors, nothing.