Merge pull request #151 from velour/dedupe

slackApp: add dedupe
This commit is contained in:
Chris Sexton 2019-02-18 18:48:47 -05:00 committed by GitHub
commit 998bc2d069
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package slackapp
import ( import (
"bytes" "bytes"
"container/ring"
"encoding/json" "encoding/json"
"fmt" "fmt"
"html" "html"
@ -23,6 +24,8 @@ import (
"github.com/velour/catbase/config" "github.com/velour/catbase/config"
) )
const DEFAULT_RING = 5
type SlackApp struct { type SlackApp struct {
bot bot.Bot bot bot.Bot
config *config.Config config *config.Config
@ -40,6 +43,8 @@ type SlackApp struct {
emoji map[string]string emoji map[string]string
event bot.Callback event bot.Callback
msgIDBuffer *ring.Ring
} }
func New(c *config.Config) *SlackApp { func New(c *config.Config) *SlackApp {
@ -50,6 +55,12 @@ func New(c *config.Config) *SlackApp {
api := slack.New(token, slack.OptionDebug(false)) api := slack.New(token, slack.OptionDebug(false))
idBuf := ring.New(c.GetInt("ringSize", DEFAULT_RING))
for i := 0; i < idBuf.Len(); i++ {
idBuf.Value = ""
idBuf = idBuf.Next()
}
return &SlackApp{ return &SlackApp{
api: api, api: api,
config: c, config: c,
@ -60,6 +71,7 @@ func New(c *config.Config) *SlackApp {
lastRecieved: time.Now(), lastRecieved: time.Now(),
users: make(map[string]string), users: make(map[string]string),
emoji: make(map[string]string), emoji: make(map[string]string),
msgIDBuffer: idBuf,
} }
} }
@ -106,7 +118,28 @@ func (s *SlackApp) Serve() error {
return nil return nil
} }
// checkRingOrAdd returns true if it finds the ts value
// or false if the ts isn't yet in the ring (and adds it)
func (s *SlackApp) checkRingOrAdd(ts string) bool {
found := false
s.msgIDBuffer.Do(func(p interface{}) {
if p.(string) == ts {
found = true
}
})
if found {
return true
}
s.msgIDBuffer.Value = ts
s.msgIDBuffer = s.msgIDBuffer.Next()
return false
}
func (s *SlackApp) msgReceivd(msg *slackevents.MessageEvent) { func (s *SlackApp) msgReceivd(msg *slackevents.MessageEvent) {
if s.checkRingOrAdd(msg.TimeStamp) {
log.Printf("Got a duplicate message from server: %s", msg.TimeStamp)
return
}
isItMe := msg.BotID != "" && msg.BotID == s.myBotID isItMe := msg.BotID != "" && msg.BotID == s.myBotID
if !isItMe && msg.ThreadTimeStamp == "" { if !isItMe && msg.ThreadTimeStamp == "" {
m := s.buildMessage(msg) m := s.buildMessage(msg)

View File

@ -0,0 +1,58 @@
package slackapp
import (
"container/ring"
"testing"
"github.com/stretchr/testify/assert"
)
func TestDedupeNoDupes(t *testing.T) {
buf := ring.New(3)
for i := 0; i < 3; i++ {
buf.Value = ""
buf = buf.Next()
}
s := SlackApp{msgIDBuffer: buf}
expected := []bool{
false,
false,
false,
false,
false,
}
actuals := []bool{}
actuals = append(actuals, s.checkRingOrAdd("a"))
actuals = append(actuals, s.checkRingOrAdd("b"))
actuals = append(actuals, s.checkRingOrAdd("c"))
actuals = append(actuals, s.checkRingOrAdd("d"))
actuals = append(actuals, s.checkRingOrAdd("e"))
assert.ElementsMatch(t, expected, actuals)
}
func TestDedupeWithDupes(t *testing.T) {
buf := ring.New(3)
for i := 0; i < 3; i++ {
buf.Value = ""
buf = buf.Next()
}
s := SlackApp{msgIDBuffer: buf}
expected := []bool{
false,
false,
true,
false,
true,
}
actuals := []bool{}
actuals = append(actuals, s.checkRingOrAdd("a"))
actuals = append(actuals, s.checkRingOrAdd("b"))
actuals = append(actuals, s.checkRingOrAdd("a"))
actuals = append(actuals, s.checkRingOrAdd("d"))
actuals = append(actuals, s.checkRingOrAdd("d"))
assert.ElementsMatch(t, expected, actuals)
}