diff --git a/activity.go b/activity.go index 1b24919..b415c19 100644 --- a/activity.go +++ b/activity.go @@ -29,7 +29,6 @@ import ( "os" "regexp" "strings" - "sync" "time" "humungus.tedunangst.com/r/webs/htfilter" @@ -257,57 +256,33 @@ type Box struct { Shared string } -var boxofboxes = make(map[string]*Box) -var boxlock sync.Mutex -var boxinglock sync.Mutex - -func getboxes(ident string) (*Box, error) { - boxlock.Lock() - b, ok := boxofboxes[ident] - boxlock.Unlock() - if ok { - return b, nil - } - - boxinglock.Lock() - defer boxinglock.Unlock() - - boxlock.Lock() - b, ok = boxofboxes[ident] - boxlock.Unlock() - if ok { - return b, nil - } - +var boxofboxes = cacheNew(cacheOptions{Filler: func(ident string) (*Box, bool) { var info string row := stmtGetXonker.QueryRow(ident, "boxes") err := row.Scan(&info) - if err != nil { - j, err := GetJunk(ident) - if err != nil { - return nil, err - } - inbox, _ := j.GetString("inbox") - outbox, _ := j.GetString("outbox") - sbox, _ := j.FindString([]string{"endpoints", "sharedInbox"}) - b = &Box{In: inbox, Out: outbox, Shared: sbox} - if inbox != "" { - m := strings.Join([]string{inbox, outbox, sbox}, " ") - _, err = stmtSaveXonker.Exec(ident, m, "boxes") - if err != nil { - log.Printf("error saving boxes: %s", err) - } - } - } else { + if err == nil { m := strings.Split(info, " ") - b = &Box{In: m[0], Out: m[1], Shared: m[2]} + b := &Box{In: m[0], Out: m[1], Shared: m[2]} + return b, true } - - boxlock.Lock() - boxofboxes[ident] = b - boxlock.Unlock() - return b, nil -} + j, err := GetJunk(ident) + if err != nil { + log.Printf("error getting boxes: %s", err) + return nil, false + } + inbox, _ := j.GetString("inbox") + outbox, _ := j.GetString("outbox") + sbox, _ := j.FindString([]string{"endpoints", "sharedInbox"}) + b := &Box{In: inbox, Out: outbox, Shared: sbox} + if inbox != "" { + m := strings.Join([]string{inbox, outbox, sbox}, " ") + _, err = stmtSaveXonker.Exec(ident, m, "boxes") + if err != nil { + log.Printf("error saving boxes: %s", err) + } + } + return b, true +}}) func gimmexonks(user *WhatAbout, outbox string) { log.Printf("getting outbox: %s", outbox) @@ -358,9 +333,10 @@ func peeppeep() { continue } log.Printf("getting updates: %s", f.XID) - box, err := getboxes(f.XID) - if err != nil { - log.Printf("error getting outbox: %s", err) + var box *Box + ok := boxofboxes.Get(f.XID, &box) + if !ok { + log.Printf("error getting outbox") continue } gimmexonks(user, box.Out) @@ -1137,8 +1113,9 @@ func honkworldwide(user *WhatAbout, honk *Honk) { if a == thewholeworld || a == user.URL || strings.HasSuffix(a, "/followers") { continue } - box, _ := getboxes(a) - if box != nil && honk.Public && box.Shared != "" { + var box *Box + ok := boxofboxes.Get(a, &box) + if ok && honk.Public && box.Shared != "" { rcpts["%"+box.Shared] = true } else { rcpts[a] = true @@ -1149,8 +1126,9 @@ func honkworldwide(user *WhatAbout, honk *Honk) { if f.XID == user.URL { continue } - box, _ := getboxes(f.XID) - if box != nil && box.Shared != "" { + var box *Box + ok := boxofboxes.Get(f.XID, &box) + if ok && box.Shared != "" { rcpts["%"+box.Shared] = true } else { rcpts[f.XID] = true @@ -1191,41 +1169,23 @@ func asjonker(user *WhatAbout) junk.Junk { return j } -var handfull = make(map[string]string) -var handlock sync.Mutex - -func gofish(name string) string { - if name[0] == '@' { - name = name[1:] - } +var handfull = cacheNew(cacheOptions{Filler: func(name string) (string, bool) { m := strings.Split(name, "@") if len(m) != 2 { log.Printf("bad fish name: %s", name) - return "" - } - handlock.Lock() - ref, ok := handfull[name] - handlock.Unlock() - if ok { - return ref + return "", true } row := stmtGetXonker.QueryRow(name, "fishname") var href string err := row.Scan(&href) if err == nil { - handlock.Lock() - handfull[name] = href - handlock.Unlock() - return href + return href, true } log.Printf("fishing for %s", name) j, err := GetJunkFast(fmt.Sprintf("https://%s/.well-known/webfinger?resource=acct:%s", m[1], name)) if err != nil { log.Printf("failed to go fish %s: %s", name, err) - handlock.Lock() - handfull[name] = "" - handlock.Unlock() - return "" + return "", true } links, _ := j.GetArray("links") for _, li := range links { @@ -1241,16 +1201,19 @@ func gofish(name string) string { if err != nil { log.Printf("error saving fishname: %s", err) } - handlock.Lock() - handfull[name] = href - handlock.Unlock() - return href + return href, true } } - handlock.Lock() - handfull[name] = "" - handlock.Unlock() - return "" + return href, true +}}) + +func gofish(name string) string { + if name[0] == '@' { + name = name[1:] + } + var href string + handfull.Get(name, &href) + return href } func isactor(t string) bool { diff --git a/cache.go b/cache.go index 9ab7230..e89d039 100644 --- a/cache.go +++ b/cache.go @@ -22,15 +22,20 @@ import ( type cacheFiller func(key interface{}) (interface{}, bool) +type cacheOptions struct { + Filler interface{} +} + type Cache struct { cache map[interface{}]interface{} filler cacheFiller lock sync.Mutex } -func cacheNew(fillfn interface{}) *Cache { +func cacheNew(options cacheOptions) *Cache { c := new(Cache) c.cache = make(map[interface{}]interface{}) + fillfn := options.Filler ftype := reflect.TypeOf(fillfn) if ftype.Kind() != reflect.Func { panic("cache filler is not function") diff --git a/deliverator.go b/deliverator.go index 9d9c9e2..00bc47c 100644 --- a/deliverator.go +++ b/deliverator.go @@ -91,9 +91,10 @@ func deliverate(goarounds int, username string, rcpt string, msg []byte) { if rcpt[0] == '%' { inbox = rcpt[1:] } else { - box, err := getboxes(rcpt) - if err != nil { - log.Printf("error getting inbox %s: %s", rcpt, err) + var box *Box + ok := boxofboxes.Get(rcpt, &box) + if !ok { + log.Printf("failed getting inbox for %s", rcpt) sayitagain(goarounds+1, username, rcpt, msg) return } diff --git a/hfcs.go b/hfcs.go index 5f05695..40bd30e 100644 --- a/hfcs.go +++ b/hfcs.go @@ -63,7 +63,7 @@ func (ft filtType) String() string { type afiltermap map[filtType][]*Filter -var filtcache = cacheNew(func(userid int64) (afiltermap, bool) { +var filtcache = cacheNew(cacheOptions{Filler: func(userid int64) (afiltermap, bool) { rows, err := stmtGetFilters.Query(userid) if err != nil { log.Printf("error querying filters: %s", err) @@ -126,7 +126,7 @@ var filtcache = cacheNew(func(userid int64) (afiltermap, bool) { return sorting[i].Name < sorting[j].Name }) return filtmap, true -}) +}}) func getfilters(userid int64, scope filtType) []*Filter { var filtmap afiltermap diff --git a/web.go b/web.go index c76025a..c940afd 100644 --- a/web.go +++ b/web.go @@ -219,9 +219,10 @@ func crappola(j junk.Junk) bool { } func ping(user *WhatAbout, who string) { - box, err := getboxes(who) - if err != nil { - log.Printf("no inbox for ping: %s", err) + var box *Box + ok := boxofboxes.Get(who, &box) + if !ok { + log.Printf("no inbox to ping %s", who) return } j := junk.New() @@ -231,7 +232,7 @@ func ping(user *WhatAbout, who string) { j["actor"] = user.URL j["to"] = who keyname, key := ziggy(user.Name) - err = PostJunk(keyname, key, box.In, j) + err := PostJunk(keyname, key, box.In, j) if err != nil { log.Printf("can't send ping: %s", err) return @@ -240,9 +241,10 @@ func ping(user *WhatAbout, who string) { } func pong(user *WhatAbout, who string, obj string) { - box, err := getboxes(who) - if err != nil { - log.Printf("no inbox for pong %s : %s", who, err) + var box *Box + ok := boxofboxes.Get(who, &box) + if !ok { + log.Printf("no inbox to pong %s", who) return } j := junk.New() @@ -253,7 +255,7 @@ func pong(user *WhatAbout, who string, obj string) { j["to"] = who j["object"] = obj keyname, key := ziggy(user.Name) - err = PostJunk(keyname, key, box.In, j) + err := PostJunk(keyname, key, box.In, j) if err != nil { log.Printf("can't send pong: %s", err) return @@ -1153,7 +1155,7 @@ func showhonkers(w http.ResponseWriter, r *http.Request) { } } -var combocache = cacheNew(func(userid int64) ([]string, bool) { +var combocache = cacheNew(cacheOptions{Filler: func(userid int64) ([]string, bool) { honkers := gethonkers(userid) var combos []string for _, h := range honkers { @@ -1167,7 +1169,7 @@ var combocache = cacheNew(func(userid int64) ([]string, bool) { combos = oneofakind(combos) sort.Strings(combos) return combos, true -}) +}}) func showcombos(w http.ResponseWriter, r *http.Request) { userinfo := login.GetUserInfo(r)