optimizing badger cache, won a 10-15% improvement in most benchmarks
This commit is contained in:
@@ -76,6 +76,10 @@ type C struct {
|
||||
NIP43PublishMemberList bool `env:"ORLY_NIP43_PUBLISH_MEMBER_LIST" default:"true" usage:"publish kind 13534 membership list events"`
|
||||
NIP43InviteExpiry time.Duration `env:"ORLY_NIP43_INVITE_EXPIRY" default:"24h" usage:"how long invite codes remain valid"`
|
||||
|
||||
// Database configuration
|
||||
DBType string `env:"ORLY_DB_TYPE" default:"badger" usage:"database backend to use: badger or dgraph"`
|
||||
DgraphURL string `env:"ORLY_DGRAPH_URL" default:"localhost:9080" usage:"dgraph gRPC endpoint address (only used when ORLY_DB_TYPE=dgraph)"`
|
||||
|
||||
// TLS configuration
|
||||
TLSDomains []string `env:"ORLY_TLS_DOMAINS" usage:"comma-separated list of domains to respond to for TLS"`
|
||||
Certs []string `env:"ORLY_CERTS" usage:"comma-separated list of paths to certificate root names (e.g., /path/to/cert will load /path/to/cert.pem and /path/to/cert.key)"`
|
||||
|
||||
@@ -60,7 +60,7 @@ func (l *Listener) HandleAuth(b []byte) (err error) {
|
||||
// handleFirstTimeUser checks if user is logging in for first time and creates welcome note
|
||||
func (l *Listener) handleFirstTimeUser(pubkey []byte) {
|
||||
// Check if this is a first-time user
|
||||
isFirstTime, err := l.Server.D.IsFirstTimeUser(pubkey)
|
||||
isFirstTime, err := l.Server.DB.IsFirstTimeUser(pubkey)
|
||||
if err != nil {
|
||||
log.E.F("failed to check first-time user status: %v", err)
|
||||
return
|
||||
|
||||
@@ -78,7 +78,7 @@ func (l *Listener) HandleCount(msg []byte) (err error) {
|
||||
}
|
||||
var cnt int
|
||||
var a bool
|
||||
cnt, a, err = l.D.CountEvents(ctx, f)
|
||||
cnt, a, err = l.DB.CountEvents(ctx, f)
|
||||
if chk.E(err) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
func (l *Listener) GetSerialsFromFilter(f *filter.F) (
|
||||
sers types.Uint40s, err error,
|
||||
) {
|
||||
return l.D.GetSerialsFromFilter(f)
|
||||
return l.DB.GetSerialsFromFilter(f)
|
||||
}
|
||||
|
||||
func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
@@ -89,7 +89,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
if len(sers) > 0 {
|
||||
for _, s := range sers {
|
||||
var ev *event.E
|
||||
if ev, err = l.FetchEventBySerial(s); chk.E(err) {
|
||||
if ev, err = l.DB.FetchEventBySerial(s); chk.E(err) {
|
||||
continue
|
||||
}
|
||||
// Only delete events that match the a-tag criteria:
|
||||
@@ -127,7 +127,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
hex.Enc(ev.ID), at.Kind.K, hex.Enc(at.Pubkey),
|
||||
string(at.DTag), ev.CreatedAt, env.E.CreatedAt,
|
||||
)
|
||||
if err = l.DeleteEventBySerial(
|
||||
if err = l.DB.DeleteEventBySerial(
|
||||
l.Ctx(), s, ev,
|
||||
); chk.E(err) {
|
||||
log.E.F("HandleDelete: failed to delete event %s: %v", hex.Enc(ev.ID), err)
|
||||
@@ -171,7 +171,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
// delete them all
|
||||
for _, s := range sers {
|
||||
var ev *event.E
|
||||
if ev, err = l.FetchEventBySerial(s); chk.E(err) {
|
||||
if ev, err = l.DB.FetchEventBySerial(s); chk.E(err) {
|
||||
continue
|
||||
}
|
||||
// Debug: log the comparison details
|
||||
@@ -199,7 +199,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
"HandleDelete: deleting event %s by authorized user %s",
|
||||
hex.Enc(ev.ID), hex.Enc(env.E.Pubkey),
|
||||
)
|
||||
if err = l.DeleteEventBySerial(l.Ctx(), s, ev); chk.E(err) {
|
||||
if err = l.DB.DeleteEventBySerial(l.Ctx(), s, ev); chk.E(err) {
|
||||
log.E.F("HandleDelete: failed to delete event %s: %v", hex.Enc(ev.ID), err)
|
||||
continue
|
||||
}
|
||||
@@ -233,7 +233,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
// delete old ones, so we can just delete them all
|
||||
for _, s := range sers {
|
||||
var ev *event.E
|
||||
if ev, err = l.FetchEventBySerial(s); chk.E(err) {
|
||||
if ev, err = l.DB.FetchEventBySerial(s); chk.E(err) {
|
||||
continue
|
||||
}
|
||||
// For admin/owner deletes: allow deletion regardless of pubkey match
|
||||
@@ -246,7 +246,7 @@ func (l *Listener) HandleDelete(env *eventenvelope.Submission) (err error) {
|
||||
"HandleDelete: deleting event %s via k-tag by authorized user %s",
|
||||
hex.Enc(ev.ID), hex.Enc(env.E.Pubkey),
|
||||
)
|
||||
if err = l.DeleteEventBySerial(l.Ctx(), s, ev); chk.E(err) {
|
||||
if err = l.DB.DeleteEventBySerial(l.Ctx(), s, ev); chk.E(err) {
|
||||
log.E.F("HandleDelete: failed to delete event %s: %v", hex.Enc(ev.ID), err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -396,7 +396,7 @@ func (l *Listener) HandleEvent(msg []byte) (err error) {
|
||||
env.E.Pubkey,
|
||||
)
|
||||
log.I.F("delete event pubkey hex: %s", hex.Enc(env.E.Pubkey))
|
||||
if _, err = l.SaveEvent(saveCtx, env.E); err != nil {
|
||||
if _, err = l.DB.SaveEvent(saveCtx, env.E); err != nil {
|
||||
log.E.F("failed to save delete event %0x: %v", env.E.ID, err)
|
||||
if strings.HasPrefix(err.Error(), "blocked:") {
|
||||
errStr := err.Error()[len("blocked: "):len(err.Error())]
|
||||
@@ -446,7 +446,7 @@ func (l *Listener) HandleEvent(msg []byte) (err error) {
|
||||
// check if the event was deleted
|
||||
// Combine admins and owners for deletion checking
|
||||
adminOwners := append(l.Admins, l.Owners...)
|
||||
if err = l.CheckForDeleted(env.E, adminOwners); err != nil {
|
||||
if err = l.DB.CheckForDeleted(env.E, adminOwners); err != nil {
|
||||
if strings.HasPrefix(err.Error(), "blocked:") {
|
||||
errStr := err.Error()[len("blocked: "):len(err.Error())]
|
||||
if err = Ok.Error(
|
||||
@@ -461,7 +461,7 @@ func (l *Listener) HandleEvent(msg []byte) (err error) {
|
||||
saveCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
// log.I.F("saving event %0x, %s", env.E.ID, env.E.Serialize())
|
||||
if _, err = l.SaveEvent(saveCtx, env.E); err != nil {
|
||||
if _, err = l.DB.SaveEvent(saveCtx, env.E); err != nil {
|
||||
if strings.HasPrefix(err.Error(), "blocked:") {
|
||||
errStr := err.Error()[len("blocked: "):len(err.Error())]
|
||||
if err = Ok.Error(
|
||||
|
||||
@@ -27,7 +27,7 @@ func (l *Listener) HandleNIP43JoinRequest(ev *event.E) error {
|
||||
}
|
||||
|
||||
// Check if user is already a member
|
||||
isMember, err := l.D.IsNIP43Member(ev.Pubkey)
|
||||
isMember, err := l.DB.IsNIP43Member(ev.Pubkey)
|
||||
if chk.E(err) {
|
||||
log.E.F("error checking membership: %v", err)
|
||||
return l.sendOKResponse(ev.ID, false, "error: internal server error")
|
||||
@@ -47,7 +47,7 @@ func (l *Listener) HandleNIP43JoinRequest(ev *event.E) error {
|
||||
}
|
||||
|
||||
// Add the member
|
||||
if err = l.D.AddNIP43Member(ev.Pubkey, inviteCode); chk.E(err) {
|
||||
if err = l.DB.AddNIP43Member(ev.Pubkey, inviteCode); chk.E(err) {
|
||||
log.E.F("error adding member: %v", err)
|
||||
return l.sendOKResponse(ev.ID, false, "error: failed to add member")
|
||||
}
|
||||
@@ -88,7 +88,7 @@ func (l *Listener) HandleNIP43LeaveRequest(ev *event.E) error {
|
||||
}
|
||||
|
||||
// Check if user is a member
|
||||
isMember, err := l.D.IsNIP43Member(ev.Pubkey)
|
||||
isMember, err := l.DB.IsNIP43Member(ev.Pubkey)
|
||||
if chk.E(err) {
|
||||
log.E.F("error checking membership: %v", err)
|
||||
return l.sendOKResponse(ev.ID, false, "error: internal server error")
|
||||
@@ -100,7 +100,7 @@ func (l *Listener) HandleNIP43LeaveRequest(ev *event.E) error {
|
||||
}
|
||||
|
||||
// Remove the member
|
||||
if err = l.D.RemoveNIP43Member(ev.Pubkey); chk.E(err) {
|
||||
if err = l.DB.RemoveNIP43Member(ev.Pubkey); chk.E(err) {
|
||||
log.E.F("error removing member: %v", err)
|
||||
return l.sendOKResponse(ev.ID, false, "error: failed to remove member")
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func (s *Server) HandleNIP43InviteRequest(pubkey []byte) (*event.E, error) {
|
||||
|
||||
// publishAddUserEvent publishes a kind 8000 add user event
|
||||
func (l *Listener) publishAddUserEvent(userPubkey []byte) error {
|
||||
relaySecret, err := l.D.GetOrCreateRelayIdentitySecret()
|
||||
relaySecret, err := l.DB.GetOrCreateRelayIdentitySecret()
|
||||
if chk.E(err) {
|
||||
return err
|
||||
}
|
||||
@@ -173,7 +173,7 @@ func (l *Listener) publishAddUserEvent(userPubkey []byte) error {
|
||||
// Save to database
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if _, err = l.SaveEvent(ctx, ev); chk.E(err) {
|
||||
if _, err = l.DB.SaveEvent(ctx, ev); chk.E(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func (l *Listener) publishAddUserEvent(userPubkey []byte) error {
|
||||
|
||||
// publishRemoveUserEvent publishes a kind 8001 remove user event
|
||||
func (l *Listener) publishRemoveUserEvent(userPubkey []byte) error {
|
||||
relaySecret, err := l.D.GetOrCreateRelayIdentitySecret()
|
||||
relaySecret, err := l.DB.GetOrCreateRelayIdentitySecret()
|
||||
if chk.E(err) {
|
||||
return err
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func (l *Listener) publishRemoveUserEvent(userPubkey []byte) error {
|
||||
// Save to database
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if _, err = l.SaveEvent(ctx, ev); chk.E(err) {
|
||||
if _, err = l.DB.SaveEvent(ctx, ev); chk.E(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -213,12 +213,12 @@ func (l *Listener) publishRemoveUserEvent(userPubkey []byte) error {
|
||||
// publishMembershipList publishes a kind 13534 membership list event
|
||||
func (l *Listener) publishMembershipList() error {
|
||||
// Get all members
|
||||
members, err := l.D.GetAllNIP43Members()
|
||||
members, err := l.DB.GetAllNIP43Members()
|
||||
if chk.E(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
relaySecret, err := l.D.GetOrCreateRelayIdentitySecret()
|
||||
relaySecret, err := l.DB.GetOrCreateRelayIdentitySecret()
|
||||
if chk.E(err) {
|
||||
return err
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func (l *Listener) publishMembershipList() error {
|
||||
// Save to database
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if _, err = l.SaveEvent(ctx, ev); chk.E(err) {
|
||||
if _, err = l.DB.SaveEvent(ctx, ev); chk.E(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ func (s *Server) HandleRelayInfo(w http.ResponseWriter, r *http.Request) {
|
||||
log.I.Ln("supported NIPs", supportedNIPs)
|
||||
// Get relay identity pubkey as hex
|
||||
var relayPubkey string
|
||||
if skb, err := s.D.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
||||
if skb, err := s.DB.GetRelayIdentitySecret(); err == nil && len(skb) == 32 {
|
||||
var sign *p8k.Signer
|
||||
var sigErr error
|
||||
if sign, sigErr = p8k.New(); sigErr == nil {
|
||||
|
||||
@@ -239,12 +239,12 @@ func (l *Listener) getManagedACL() *database.ManagedACL {
|
||||
|
||||
// QueryEvents queries events using the database QueryEvents method
|
||||
func (l *Listener) QueryEvents(ctx context.Context, f *filter.F) (event.S, error) {
|
||||
return l.D.QueryEvents(ctx, f)
|
||||
return l.DB.QueryEvents(ctx, f)
|
||||
}
|
||||
|
||||
// QueryAllVersions queries events using the database QueryAllVersions method
|
||||
func (l *Listener) QueryAllVersions(ctx context.Context, f *filter.F) (event.S, error) {
|
||||
return l.D.QueryAllVersions(ctx, f)
|
||||
return l.DB.QueryAllVersions(ctx, f)
|
||||
}
|
||||
|
||||
// canSeePrivateEvent checks if the authenticated user can see an event with a private tag
|
||||
|
||||
21
app/main.go
21
app/main.go
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
func Run(
|
||||
ctx context.Context, cfg *config.C, db *database.D,
|
||||
ctx context.Context, cfg *config.C, db database.Database,
|
||||
) (quit chan struct{}) {
|
||||
quit = make(chan struct{})
|
||||
var once sync.Once
|
||||
@@ -65,7 +65,7 @@ func Run(
|
||||
l := &Server{
|
||||
Ctx: ctx,
|
||||
Config: cfg,
|
||||
D: db,
|
||||
DB: db,
|
||||
publishers: publish.New(NewPublisher(ctx)),
|
||||
Admins: adminKeys,
|
||||
Owners: ownerKeys,
|
||||
@@ -87,7 +87,7 @@ func Run(
|
||||
|
||||
// Initialize spider manager based on mode
|
||||
if cfg.SpiderMode != "none" {
|
||||
if l.spiderManager, err = spider.New(ctx, db, l.publishers, cfg.SpiderMode); chk.E(err) {
|
||||
if l.spiderManager, err = spider.New(ctx, db.(*database.D), l.publishers, cfg.SpiderMode); chk.E(err) {
|
||||
log.E.F("failed to create spider manager: %v", err)
|
||||
} else {
|
||||
// Set up callbacks for follows mode
|
||||
@@ -142,7 +142,7 @@ func Run(
|
||||
}
|
||||
|
||||
// Initialize relay group manager
|
||||
l.relayGroupMgr = dsync.NewRelayGroupManager(db, cfg.RelayGroupAdmins)
|
||||
l.relayGroupMgr = dsync.NewRelayGroupManager(db.(*database.D), cfg.RelayGroupAdmins)
|
||||
|
||||
// Initialize sync manager if relay peers are configured
|
||||
var peers []string
|
||||
@@ -170,7 +170,7 @@ func Run(
|
||||
if relayURL == "" {
|
||||
relayURL = fmt.Sprintf("http://localhost:%d", cfg.Port)
|
||||
}
|
||||
l.syncManager = dsync.NewManager(ctx, db, nodeID, relayURL, peers, l.relayGroupMgr, l.policyManager)
|
||||
l.syncManager = dsync.NewManager(ctx, db.(*database.D), nodeID, relayURL, peers, l.relayGroupMgr, l.policyManager)
|
||||
log.I.F("distributed sync manager initialized with %d peers", len(peers))
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func Run(
|
||||
}
|
||||
|
||||
if len(clusterAdminNpubs) > 0 {
|
||||
l.clusterManager = dsync.NewClusterManager(ctx, db, clusterAdminNpubs, cfg.ClusterPropagatePrivilegedEvents, l.publishers)
|
||||
l.clusterManager = dsync.NewClusterManager(ctx, db.(*database.D), clusterAdminNpubs, cfg.ClusterPropagatePrivilegedEvents, l.publishers)
|
||||
l.clusterManager.Start()
|
||||
log.I.F("cluster replication manager initialized with %d admin npubs", len(clusterAdminNpubs))
|
||||
}
|
||||
@@ -197,7 +197,7 @@ func Run(
|
||||
l.UserInterface()
|
||||
|
||||
// Initialize Blossom blob storage server
|
||||
if l.blossomServer, err = initializeBlossomServer(ctx, cfg, db); err != nil {
|
||||
if l.blossomServer, err = initializeBlossomServer(ctx, cfg, db.(*database.D)); err != nil {
|
||||
log.E.F("failed to initialize blossom server: %v", err)
|
||||
// Continue without blossom server
|
||||
} else if l.blossomServer != nil {
|
||||
@@ -237,7 +237,7 @@ func Run(
|
||||
}
|
||||
}
|
||||
|
||||
if l.paymentProcessor, err = NewPaymentProcessor(ctx, cfg, db); err != nil {
|
||||
if l.paymentProcessor, err = NewPaymentProcessor(ctx, cfg, db.(*database.D)); err != nil {
|
||||
// log.E.F("failed to create payment processor: %v", err)
|
||||
// Continue without payment processor
|
||||
} else {
|
||||
@@ -248,6 +248,11 @@ func Run(
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for database to be ready before accepting requests
|
||||
log.I.F("waiting for database warmup to complete...")
|
||||
<-db.Ready()
|
||||
log.I.F("database ready, starting HTTP servers")
|
||||
|
||||
// Check if TLS is enabled
|
||||
var tlsEnabled bool
|
||||
var tlsServer *http.Server
|
||||
|
||||
@@ -39,7 +39,7 @@ type Server struct {
|
||||
publishers *publish.S
|
||||
Admins [][]byte
|
||||
Owners [][]byte
|
||||
*database.D
|
||||
DB database.Database // Changed from embedded *database.D to interface field
|
||||
|
||||
// optional reverse proxy for dev web server
|
||||
devProxy *httputil.ReverseProxy
|
||||
@@ -58,7 +58,7 @@ type Server struct {
|
||||
blossomServer *blossom.Server
|
||||
InviteManager *nip43.InviteManager
|
||||
cfg *config.C
|
||||
db *database.D
|
||||
db database.Database // Changed from *database.D to interface
|
||||
}
|
||||
|
||||
// isIPBlacklisted checks if an IP address is blacklisted using the managed ACL system
|
||||
@@ -612,7 +612,7 @@ func (s *Server) handleExport(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
|
||||
// Stream export
|
||||
s.D.Export(s.Ctx, w, pks...)
|
||||
s.DB.Export(s.Ctx, w, pks...)
|
||||
}
|
||||
|
||||
// handleEventsMine returns the authenticated user's events in JSON format with pagination using NIP-98 authentication.
|
||||
@@ -655,7 +655,7 @@ func (s *Server) handleEventsMine(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
log.Printf("DEBUG: Querying events for pubkey: %s", hex.Enc(pubkey))
|
||||
events, err := s.D.QueryEvents(s.Ctx, f)
|
||||
events, err := s.DB.QueryEvents(s.Ctx, f)
|
||||
if chk.E(err) {
|
||||
log.Printf("DEBUG: QueryEvents failed: %v", err)
|
||||
http.Error(w, "Failed to query events", http.StatusInternalServerError)
|
||||
@@ -742,13 +742,13 @@ func (s *Server) handleImport(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
s.D.Import(file)
|
||||
s.DB.Import(file)
|
||||
} else {
|
||||
if r.Body == nil {
|
||||
http.Error(w, "Empty request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
s.D.Import(r.Body)
|
||||
s.DB.Import(r.Body)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
Reference in New Issue
Block a user