khatru: fix bbolt halting problem by deleting outside of the loop that fetches events to be deleted.
fixes nostr:nevent1qvzqqqqx25pzq2f38nys0gq4hs5k4l4s426689psdk7d52kzjk9s0ypne2nt7927qy88wumn8ghj7mn0wvhxcmmv9uq32amnwvaz7tmjv4kxz7fwv3sk6atn9e5k7tcqyphrdv7jerr3f5mtlpcl7j7dg26ecxj9vrd5pyf0jknkqmp5qyyj28gxd3q
This commit is contained in:
67
eventstore/boltdb/halt_test.go
Normal file
67
eventstore/boltdb/halt_test.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package boltdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"fiatjaf.com/nostr"
|
||||||
|
"fiatjaf.com/nostr/khatru"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHaltingProblem(t *testing.T) {
|
||||||
|
go func() {
|
||||||
|
if err := os.RemoveAll("/tmp/bolthalttest"); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
db := BoltBackend{Path: "/tmp/bolthalttest"}
|
||||||
|
if err := db.Init(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
relay := khatru.NewRelay()
|
||||||
|
relay.UseEventstore(&db, 500)
|
||||||
|
|
||||||
|
server := &http.Server{Addr: ":54898", Handler: relay}
|
||||||
|
server.ListenAndServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 200)
|
||||||
|
client, err := nostr.RelayConnect(t.Context(), "http://127.0.0.1:54898", nostr.RelayOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
sk := nostr.Generate()
|
||||||
|
var id nostr.ID
|
||||||
|
|
||||||
|
{
|
||||||
|
evt := nostr.Event{
|
||||||
|
CreatedAt: nostr.Now(),
|
||||||
|
Content: "",
|
||||||
|
Kind: nostr.Kind(1),
|
||||||
|
}
|
||||||
|
evt.Sign(sk)
|
||||||
|
err := client.Publish(context.Background(), evt)
|
||||||
|
require.NoError(t, err)
|
||||||
|
id = evt.ID
|
||||||
|
t.Logf("event published: %s\n", id.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
evt := nostr.Event{
|
||||||
|
CreatedAt: nostr.Now(),
|
||||||
|
Tags: nostr.Tags{
|
||||||
|
nostr.Tag{"e", id.Hex()},
|
||||||
|
},
|
||||||
|
Kind: nostr.Kind(5),
|
||||||
|
}
|
||||||
|
evt.Sign(sk)
|
||||||
|
|
||||||
|
err := client.Publish(context.Background(), evt)
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Logf("event deleted\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"fiatjaf.com/nostr"
|
"fiatjaf.com/nostr"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -61,20 +62,24 @@ func (rl *Relay) handleDeleteRequest(ctx context.Context, evt nostr.Event) error
|
|||||||
|
|
||||||
ctx := context.WithValue(ctx, internalCallKey, struct{}{})
|
ctx := context.WithValue(ctx, internalCallKey, struct{}{})
|
||||||
|
|
||||||
|
errg, ctx := errgroup.WithContext(ctx)
|
||||||
for target := range rl.QueryStored(ctx, f) {
|
for target := range rl.QueryStored(ctx, f) {
|
||||||
// got the event, now check if the user can delete it
|
// got the event, now check if the user can delete it
|
||||||
if target.PubKey == evt.PubKey {
|
if target.PubKey == evt.PubKey {
|
||||||
// delete it
|
// delete it
|
||||||
if err := rl.DeleteEvent(ctx, target.ID); err != nil {
|
errg.Go(func() error {
|
||||||
return err
|
if err := rl.DeleteEvent(ctx, target.ID); err != nil {
|
||||||
}
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// if it was tracked to be expired that is not needed anymore
|
// if it was tracked to be expired that is not needed anymore
|
||||||
if rl.expirationManager != nil {
|
if rl.expirationManager != nil {
|
||||||
rl.expirationManager.removeEvent(target.ID)
|
rl.expirationManager.removeEvent(target.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
haveDeletedSomething = true
|
haveDeletedSomething = true
|
||||||
|
return nil
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// fail and stop here
|
// fail and stop here
|
||||||
return ErrNotAuthor
|
return ErrNotAuthor
|
||||||
@@ -83,6 +88,10 @@ func (rl *Relay) handleDeleteRequest(ctx context.Context, evt nostr.Event) error
|
|||||||
// don't try to query this same event again
|
// don't try to query this same event again
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := errg.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user