diff --git a/bot/bot.go b/bot/bot.go index 83826be..56d25c8 100644 --- a/bot/bot.go +++ b/bot/bot.go @@ -22,6 +22,7 @@ type Bot struct { rooms sync.Map log *logger.Logger lp *linkpearl.Linkpearl + mu map[id.RoomID]*sync.Mutex handledMembershipEvents sync.Map } @@ -35,6 +36,7 @@ func New(lp *linkpearl.Linkpearl, log *logger.Logger, prefix, domain string, noo rooms: sync.Map{}, log: log, lp: lp, + mu: map[id.RoomID]*sync.Mutex{}, } } diff --git a/bot/email.go b/bot/email.go index e4849af..b82f9d5 100644 --- a/bot/email.go +++ b/bot/email.go @@ -49,6 +49,8 @@ func (b *Bot) Send(ctx context.Context, email *utils.Email) error { if !ok { return errors.New("room not found") } + b.lock(roomID) + defer b.unlock(roomID) cfg, err := b.getSettings(roomID) if err != nil { diff --git a/bot/mutext.go b/bot/mutext.go new file mode 100644 index 0000000..8bc091d --- /dev/null +++ b/bot/mutext.go @@ -0,0 +1,26 @@ +package bot + +import ( + "sync" + + "maunium.net/go/mautrix/id" +) + +func (b *Bot) lock(roomID id.RoomID) { + _, ok := b.mu[roomID] + if !ok { + b.mu[roomID] = &sync.Mutex{} + } + + b.mu[roomID].Lock() +} + +func (b *Bot) unlock(roomID id.RoomID) { + _, ok := b.mu[roomID] + if !ok { + return + } + + b.mu[roomID].Unlock() + delete(b.mu, roomID) +} diff --git a/e2e/send-stress b/e2e/send-stress new file mode 100755 index 0000000..e4b5da9 --- /dev/null +++ b/e2e/send-stress @@ -0,0 +1,8 @@ +#!/bin/bash + +for i in {0..10..1}; do + echo "#${i}..." + ssmtp test@localhost < $1 +done + +echo "done"