M activity.go +39 -30
@@ 28,6 28,7 @@ import (
"os"
"regexp"
"strings"
+ "sync"
"time"
"humungus.tedunangst.com/r/webs/gate"
@@ 426,14 427,22 @@ var boxofboxes = gencache.New(gencache.O
var j junk.Junk
j, err = GetJunk(readyLuserOne, ident)
if err != nil {
- dlog.Printf("error getting boxes: %s", err)
- return nil, false
+ dlog.Printf("error getting boxes for %s: %s", ident, err)
+ str := err.Error()
+ if strings.Contains(str, "http get status: 410") ||
+ strings.Contains(str, "http get status: 404") {
+ savexonker(ident, "dead", "boxes")
+ }
+ return nil, true
}
allinjest(originate(ident), j)
row = stmtGetXonker.QueryRow(ident, "boxes")
err = row.Scan(&info)
}
if err == nil {
+ if info == "dead" {
+ return nil, true
+ }
m := strings.Split(info, " ")
b := &Box{In: m[0], Out: m[1], Shared: m[2]}
return b, true
@@ 1653,21 1662,33 @@ func gimmejonk(xid string) ([]byte, bool
func boxuprcpts(user *WhatAbout, addresses []string, useshared bool) map[string]bool {
rcpts := make(map[string]bool)
- for _, a := range addresses {
+ var wg sync.WaitGroup
+ var mtx sync.Mutex
+ for i := range addresses {
+ a := addresses[i]
if a == "" || a == thewholeworld || a == user.URL || strings.HasSuffix(a, "/followers") {
continue
}
if a[0] == '%' {
+ mtx.Lock()
rcpts[a] = true
+ mtx.Unlock()
continue
}
- box, ok := boxofboxes.Get(a)
- if ok && useshared && box.Shared != "" {
- rcpts["%"+box.Shared] = true
- } else {
- rcpts[a] = true
- }
+ wg.Add(1)
+ go func() {
+ box, _ := boxofboxes.Get(a)
+ mtx.Lock()
+ if box != nil && useshared && box.Shared != "" {
+ rcpts["%"+box.Shared] = true
+ } else {
+ rcpts[a] = true
+ }
+ mtx.Unlock()
+ wg.Done()
+ }()
}
+ wg.Wait()
return rcpts
}
@@ 1742,35 1763,23 @@ func honkworldwide(user *WhatAbout, honk
jonk["@context"] = itiswhatitis
msg := jonk.ToBytes()
- rcpts := boxuprcpts(user, honk.Audience, honk.Public)
+ aud := honk.Audience
if honk.Public {
for _, h := range getdubs(user.ID) {
if h.XID == user.URL {
continue
}
- box, ok := boxofboxes.Get(h.XID)
- if ok && box.Shared != "" {
- rcpts["%"+box.Shared] = true
- } else {
- rcpts[h.XID] = true
- }
+ aud = append(aud, h.XID)
}
if honk.What == "update" {
for _, f := range getbacktracks(honk.XID) {
- if f[0] == '%' {
- rcpts[f] = true
- } else {
- box, ok := boxofboxes.Get(f)
- if ok && box.Shared != "" {
- rcpts["%"+box.Shared] = true
- } else {
- rcpts[f] = true
- }
- }
+ aud = append(aud, f)
}
}
}
+ rcpts := boxuprcpts(user, aud, honk.Public)
+
for a := range rcpts {
go deliverate(user.ID, a, msg)
}
@@ 1795,8 1804,8 @@ func collectiveaction(honk *Honk) {
j["target"] = serverURL("/o/%s", ont[1:])
rcpts := make(map[string]bool)
for _, dub := range dubs {
- box, ok := boxofboxes.Get(dub.XID)
- if ok && box.Shared != "" {
+ box, _ := boxofboxes.Get(dub.XID)
+ if box != nil && box.Shared != "" {
rcpts["%"+box.Shared] = true
} else {
rcpts[dub.XID] = true
@@ 2118,8 2127,8 @@ func updateMe(username string) {
if f.XID == user.URL {
continue
}
- box, ok := boxofboxes.Get(f.XID)
- if ok && box.Shared != "" {
+ box, _ := boxofboxes.Get(f.XID)
+ if box != nil && box.Shared != "" {
rcpts["%"+box.Shared] = true
} else {
rcpts[f.XID] = true
M database.go +1 -1
@@ 1221,7 1221,7 @@ func prepareStatements(db *sql.DB) {
stmtGetXonker = preparetodie(db, "select info from xonkers where name = ? and flavor = ?")
stmtSaveXonker = preparetodie(db, "insert into xonkers (name, info, flavor, dt) values (?, ?, ?, ?)")
stmtDeleteXonker = preparetodie(db, "delete from xonkers where name = ? and flavor = ? and dt < ?")
- stmtDeleteOldXonkers = preparetodie(db, "delete from xonkers where dt < ?")
+ stmtDeleteOldXonkers = preparetodie(db, "delete from xonkers where dt < ? and flavor <> 'handle'")
stmtRecentHonkers = preparetodie(db, "select distinct(honker) from honks where userid = ? and honker not in (select xid from honkers where userid = ? and flavor = 'sub') order by honkid desc limit 100")
stmtUpdateFlags = preparetodie(db, "update honks set flags = flags | ? where honkid = ?")
stmtClearFlags = preparetodie(db, "update honks set flags = flags & ~ ? where honkid = ?")
M deliverator.go +2 -2
@@ 139,8 139,8 @@ func deliveration(doover Doover) {
if rcpt[0] == '%' {
inbox = rcpt[1:]
} else {
- box, ok := boxofboxes.Get(rcpt)
- if !ok {
+ box, _ := boxofboxes.Get(rcpt)
+ if box == nil {
ilog.Printf("failed getting inbox for %s", rcpt)
if doover.Tries < nearlyDead {
doover.Tries = nearlyDead
M fun.go +43 -35
@@ 28,6 28,7 @@ import (
"regexp"
"strconv"
"strings"
+ "sync"
"time"
"golang.org/x/net/html"
@@ 65,8 66,10 @@ func loadLingo() {
}
func reverbolate(userid UserID, honks []*Honk) {
+ var handlers sync.WaitGroup
user, _ := somenumberedusers.Get(userid)
- for _, h := range honks {
+ for i := range honks {
+ h := honks[i]
h.What += "ed"
if h.What == "honked" && h.RID != "" {
h.What = "honked back"
@@ 86,43 89,47 @@ func reverbolate(userid UserID, honks []
if local && h.What != "bonked" {
h.Noise = re_memes.ReplaceAllString(h.Noise, "")
}
- h.Username, h.Handle = handles(h.Honker)
- if !local {
- short := shortname(userid, h.Honker)
- if short != "" {
- h.Username = short
- } else {
- h.Username = h.Handle
- if len(h.Username) > 20 {
- h.Username = h.Username[:20] + ".."
- }
- }
- }
- if user != nil {
- hset := []string{}
- if h.Honker != user.URL {
- hset = append(hset, "@"+h.Handle)
- }
- if user.Options.MentionAll {
- for _, a := range h.Audience {
- if a == h.Honker || a == user.URL {
- continue
- }
- _, hand := handles(a)
- if hand != "" {
- hand = "@" + hand
- hset = append(hset, hand)
+ handlers.Add(1)
+ go func() {
+ h.Username, h.Handle = handles(h.Honker)
+ if !local {
+ short := shortname(userid, h.Honker)
+ if short != "" {
+ h.Username = short
+ } else {
+ h.Username = h.Handle
+ if len(h.Username) > 20 {
+ h.Username = h.Username[:20] + ".."
}
}
}
- h.Handles = strings.Join(hset, " ")
- }
- if h.URL == "" {
- h.URL = h.XID
- }
- if h.Oonker != "" {
- _, h.Oondle = handles(h.Oonker)
- }
+ if user != nil {
+ hset := []string{}
+ if h.Honker != user.URL {
+ hset = append(hset, "@"+h.Handle)
+ }
+ if user.Options.MentionAll {
+ for _, a := range h.Audience {
+ if a == h.Honker || a == user.URL {
+ continue
+ }
+ _, hand := handles(a)
+ if hand != "" {
+ hand = "@" + hand
+ hset = append(hset, hand)
+ }
+ }
+ }
+ h.Handles = strings.Join(hset, " ")
+ }
+ if h.URL == "" {
+ h.URL = h.XID
+ }
+ if h.Oonker != "" {
+ _, h.Oondle = handles(h.Oonker)
+ }
+ handlers.Done()
+ }()
h.Precis = demoji(h.Precis)
h.Noise = demoji(h.Noise)
h.Open = "open"
@@ 201,6 208,7 @@ func reverbolate(userid UserID, honks []
}
h.Donks = h.Donks[:j]
}
+ handlers.Wait()
unsee(honks, userid)
M web.go +13 -7
@@ 365,8 365,8 @@ func ping(user *WhatAbout, who string) {
ilog.Printf("nobody to ping!")
return
}
- box, ok := boxofboxes.Get(who)
- if !ok {
+ box, _ := boxofboxes.Get(who)
+ if box == nil {
ilog.Printf("no inbox to ping %s", who)
return
}
@@ 390,8 390,8 @@ func ping(user *WhatAbout, who string) {
}
func pong(user *WhatAbout, who string, obj string) {
- box, ok := boxofboxes.Get(who)
- if !ok {
+ box, _ := boxofboxes.Get(who)
+ if box == nil {
ilog.Printf("no inbox to pong %s", who)
return
}
@@ 1233,7 1233,7 @@ func savetracks(tracks map[string][]stri
dlog.Printf("saved %d new fetches", count)
}
-var trackchan = make(chan Track)
+var trackchan = make(chan Track, 4)
var dumptracks = make(chan chan bool)
func tracker() {
@@ 1254,11 1254,13 @@ func tracker() {
case c := <-dumptracks:
if len(tracks) > 0 {
savetracks(tracks)
+ tracks = make(map[string][]string)
}
c <- true
case <-endoftheworld:
if len(tracks) > 0 {
savetracks(tracks)
+ tracks = make(map[string][]string)
}
readyalready <- true
return
@@ 1280,7 1282,10 @@ func requestActor(r *http.Request) strin
func trackback(xid string, r *http.Request) {
who := requestActor(r)
if who != "" {
- trackchan <- Track{xid: xid, who: who}
+ select {
+ case trackchan <- Track{xid: xid, who: who}:
+ default:
+ }
}
}
@@ 3103,13 3108,14 @@ func enditall() {
func bgmonitor() {
for {
+ time.Sleep(150 * time.Minute)
+ continue
when := time.Now().Add(-2 * 24 * time.Hour).UTC().Format(dbtimeformat)
_, err := stmtDeleteOldXonkers.Exec(when)
if err != nil {
elog.Printf("error deleting old xonkers: %s", err)
}
xonkInvalidator.Flush()
- time.Sleep(150 * time.Minute)
}
}