• Kirill Smelkov's avatar
    go/zodb: Fix PActivate not to panic after an error · 67f0d2cd
    Kirill Smelkov authored
    Persistent.PActivate used to panic when called the second time, if the
    first time it hit an error. WCFS hit this in practice via object, that was
    previously accessed and pinned into the cache, but later deleted in the
    storage.
    
    -> Fix PActivate to reset .loading on an error, so that next time PActivate is
    called, it tries to trigger load again instead of panicking. Change doload
    criteria from
    
    	state==GHOST && refcnt==1
    
    to
    
    	state==GHOST && loading==nil
    
    because now, after failed PActivate, refcnt can be != 0, if there are several
    other PActivate calls that were waiting for the failed PActivate but did not
    yet woke up.
    
    Here is how added test fails without the fix:
    
        --- FAIL: TestActivateAfterDelete (1.65s)
        panic: t.zodb.MyObject(0000000000000065): activate: need to load, but .loading != nil [recovered]
                panic: t.zodb.MyObject(0000000000000065): activate: need to load, but .loading != nil
    
        goroutine 10085 [running]:
        testing.tRunner.func1.2(0x649020, 0xc000520660)
                /home/kirr/src/tools/go/go/src/testing/testing.go:1143 +0x332
        testing.tRunner.func1(0xc0001cb080)
                /home/kirr/src/tools/go/go/src/testing/testing.go:1146 +0x4b6
        panic(0x649020, 0xc000520660)
                /home/kirr/src/tools/go/go/src/runtime/panic.go:965 +0x1b9
        lab.nexedi.com/kirr/neo/go/zodb.(*Persistent).PActivate(0xc0001184d0, 0x6e8360, 0xc00019ac90, 0x0, 0x0)
                /home/kirr/src/neo/src/lab.nexedi.com/kirr/neo/go/zodb/persistent.go:191 +0xce5
        lab.nexedi.com/kirr/neo/go/zodb.TestActivateAfterDelete(0xc0001cb080)
                /home/kirr/src/neo/src/lab.nexedi.com/kirr/neo/go/zodb/persistent_test.go:786 +0x72c
    67f0d2cd
persistent_test.go 22.6 KB