From 416b082c30c8227ae51e06bf01fc0719e301cf20 Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Tue, 10 Sep 2024 18:58:12 -0400
Subject: [PATCH 1/6] Alternate pubsub implementation

---
 docker-compose.override.yml |  2 +-
 go.mod                      |  3 +-
 go.sum                      |  4 ++
 imgs/cli.go                 |  7 +--
 imgs/ssh.go                 |  6 ++-
 pubsub/cli.go               | 98 ++++++++++++++++---------------------
 pubsub/ssh.go               |  5 +-
 7 files changed, 60 insertions(+), 65 deletions(-)

diff --git a/docker-compose.override.yml b/docker-compose.override.yml
index 36c7cd6a..64dea139 100644
--- a/docker-compose.override.yml
+++ b/docker-compose.override.yml
@@ -57,7 +57,7 @@ services:
   pubsub-ssh:
     build:
       args:
-        APP:pubsub
+        APP: pubsub
       target: release-ssh
     env_file:
       - .env.example
diff --git a/go.mod b/go.mod
index 3f79b3f7..d6d1b7b8 100644
--- a/go.mod
+++ b/go.mod
@@ -17,6 +17,7 @@ replace github.com/gdamore/tcell/v2 => github.com/delthas/tcell/v2 v2.4.1-0.2023
 require (
 	git.sr.ht/~delthas/senpai v0.3.1-0.20240425235039-206be659439e
 	github.com/alecthomas/chroma/v2 v2.14.0
+	github.com/antoniomika/syncmap v1.0.0
 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
 	github.com/charmbracelet/bubbles v0.18.0
 	github.com/charmbracelet/bubbletea v0.27.0
@@ -36,7 +37,7 @@ require (
 	github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5
 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
 	github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a
-	github.com/picosh/pubsub v0.0.0-20240909042445-92777a8b167b
+	github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161
 	github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc
 	github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e
 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
diff --git a/go.sum b/go.sum
index c556f3a1..fe0d7007 100644
--- a/go.sum
+++ b/go.sum
@@ -17,6 +17,8 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi
 github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
+github.com/antoniomika/syncmap v1.0.0 h1:iFSfbQFQOvHZILFZF+hqWosO0no+W9+uF4y2VEyMKWU=
+github.com/antoniomika/syncmap v1.0.0/go.mod h1:fK2829foEYnO4riNfyUn0SHQZt4ue3DStYjGU+sJj38=
 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
@@ -226,6 +228,8 @@ github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo=
 github.com/picosh/pubsub v0.0.0-20240909042445-92777a8b167b h1:/gGhT8y9rnrv8K9ZJKZYzdWvZcnazl8NGE1DGNrD8HU=
 github.com/picosh/pubsub v0.0.0-20240909042445-92777a8b167b/go.mod h1:FKC8uot+40iXmuDzTfbxYDG5PIc3ghwkmP2iItBKH0I=
+github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161 h1:XKp88wHvv7YQXl4/BfnRCOLmcONTrJK2rE7XMr3gpdw=
+github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs=
diff --git a/imgs/cli.go b/imgs/cli.go
index b759e151..8a0f3816 100644
--- a/imgs/cli.go
+++ b/imgs/cli.go
@@ -259,12 +259,13 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				opts.bail(err)
 				return
 			} else if cmd == "sub" {
-				err = pubsub.PubSub.Sub(&psub.Subscriber{
+				err = pubsub.PubSub.Sub(fmt.Sprintf("%s@%s", user.Name, repoName), &psub.Sub{
 					ID:     uuid.NewString(),
-					Name:   fmt.Sprintf("%s@%s", user.Name, repoName),
 					Writer: sesh,
-					Chan:   make(chan error),
+					Done:   make(chan struct{}),
+					Data:   make(chan []byte),
 				})
+
 				if err != nil {
 					wish.Errorln(sesh, err)
 				}
diff --git a/imgs/ssh.go b/imgs/ssh.go
index 7cc1c8a5..7f0a6a7a 100644
--- a/imgs/ssh.go
+++ b/imgs/ssh.go
@@ -20,6 +20,7 @@ import (
 
 	"github.com/charmbracelet/ssh"
 	"github.com/charmbracelet/wish"
+	"github.com/google/uuid"
 	"github.com/picosh/pico/db"
 	"github.com/picosh/pico/db/postgres"
 	"github.com/picosh/pico/shared"
@@ -229,8 +230,9 @@ func createServeMux(handler *CliHandler, pubsub *psub.Cfg) func(ctx ssh.Context)
 				)
 				handler.Logger.Info("sending event", "url", furl)
 
-				err := pubsub.PubSub.Pub(&psub.Msg{
-					Name:   fmt.Sprintf("%s@%s:%s", user.Name, img, tag),
+				err := pubsub.PubSub.Pub(fmt.Sprintf("%s@%s:%s", user.Name, img, tag), &psub.Pub{
+					ID:     uuid.NewString(),
+					Done:   make(chan struct{}),
 					Reader: strings.NewReader(furl),
 				})
 
diff --git a/pubsub/cli.go b/pubsub/cli.go
index 42b566c8..c621d843 100644
--- a/pubsub/cli.go
+++ b/pubsub/cli.go
@@ -1,6 +1,7 @@
 package pubsub
 
 import (
+	"bytes"
 	"flag"
 	"fmt"
 	"io"
@@ -66,19 +67,6 @@ func toPublicChannel(name string) string {
 	return fmt.Sprintf("public@%s", name)
 }
 
-// extract user and scoped channel from channel.
-func fromChannel(channel string) (string, string) {
-	sp := strings.SplitN(channel, "@", 2)
-	ln := len(sp)
-	if ln == 0 {
-		return "", ""
-	}
-	if ln == 1 {
-		return "", ""
-	}
-	return sp[0], sp[1]
-}
-
 var helpStr = `Commands: [pub, sub, ls]
 
 The simplest authenticated pubsub system.  Send messages through
@@ -123,26 +111,29 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				if cmd == "help" {
 					wish.Println(sesh, helpStr)
 				} else if cmd == "ls" {
-					subs := pubsub.PubSub.GetSubs()
+					channels := pubsub.PubSub.GetChannels(fmt.Sprintf("%s@", user.Name))
 
-					if len(subs) == 0 {
-						wish.Println(sesh, "no subs found")
+					if len(channels) == 0 {
+						wish.Println(sesh, "no pubsub channels found")
 					} else {
-						writer := NewTabWriter(sesh)
-						fmt.Fprintln(writer, "Channel\tID")
-						for _, sub := range subs {
-							userName, _ := fromChannel(sub.Name)
-							if userName != "public" && userName != user.Name {
-								continue
-							}
-
-							fmt.Fprintf(
-								writer,
-								"%s\t%s\n",
-								sub.Name, sub.ID,
-							)
+						outputData := "Channel Information\n"
+						for _, channel := range channels {
+							outputData += fmt.Sprintf("- %s:\n", channel.Name)
+							outputData += "\tPubs:\n"
+
+							channel.Pubs.Range(func(I string, J *psub.Pub) bool {
+								outputData += fmt.Sprintf("\t- %s:\n", I)
+								return true
+							})
+
+							outputData += "\tSubs:\n"
+
+							channel.Subs.Range(func(I string, J *psub.Sub) bool {
+								outputData += fmt.Sprintf("\t- %s:\n", I)
+								return true
+							})
 						}
-						writer.Flush()
+						sesh.Write([]byte(outputData))
 					}
 				}
 				next(sesh)
@@ -170,7 +161,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 
 				var reader io.Reader
 				if *empty {
-					reader = strings.NewReader("")
+					reader = bytes.NewReader(make([]byte, 1))
 				} else {
 					reader = sesh
 				}
@@ -181,34 +172,32 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				}
 
 				wish.Println(sesh, "sending msg ...")
-				msg := &psub.Msg{
-					Name:   name,
+				pub := &psub.Pub{
+					ID:     uuid.NewString(),
+					Done:   make(chan struct{}),
 					Reader: reader,
 				}
 
-				// hacky: we want to notify when no subs are found so
-				// we duplicate some logic for now
-				subs := pubsub.PubSub.GetSubs()
-				found := false
-				for _, sub := range subs {
-					if pubsub.PubSub.PubMatcher(msg, sub) {
-						found = true
-						break
-					}
+				count := 0
+				channelInfo := pubsub.PubSub.GetChannel(name)
+
+				if channelInfo != nil {
+					channelInfo.Subs.Range(func(I string, J *psub.Sub) bool {
+						count++
+						return true
+					})
 				}
-				if !found {
+
+				if count == 0 {
 					wish.Println(sesh, "no subs found ... waiting")
 				}
 
 				go func() {
 					<-ctx.Done()
-					err := pubsub.PubSub.UnPub(msg)
-					if err != nil {
-						wish.Errorln(sesh, err)
-					}
+					pub.Cleanup()
 				}()
 
-				err = pubsub.PubSub.Pub(msg)
+				err = pubsub.PubSub.Pub(name, pub)
 				wish.Println(sesh, "msg sent!")
 				if err != nil {
 					wish.Errorln(sesh, err)
@@ -226,21 +215,18 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 					name = toPublicChannel(channelName)
 				}
 
-				sub := &psub.Subscriber{
+				sub := &psub.Sub{
 					ID:     uuid.NewString(),
-					Name:   name,
 					Writer: sesh,
-					Chan:   make(chan error),
+					Done:   make(chan struct{}),
+					Data:   make(chan []byte),
 				}
 
 				go func() {
 					<-ctx.Done()
-					err := pubsub.PubSub.UnSub(sub)
-					if err != nil {
-						wish.Errorln(sesh, err)
-					}
+					sub.Cleanup()
 				}()
-				err = pubsub.PubSub.Sub(sub)
+				err = pubsub.PubSub.Sub(name, sub)
 				if err != nil {
 					wish.Errorln(sesh, err)
 				}
diff --git a/pubsub/ssh.go b/pubsub/ssh.go
index d0865700..5de9f0d9 100644
--- a/pubsub/ssh.go
+++ b/pubsub/ssh.go
@@ -8,6 +8,7 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/antoniomika/syncmap"
 	"github.com/charmbracelet/promwish"
 	"github.com/charmbracelet/wish"
 	"github.com/picosh/pico/db/postgres"
@@ -29,8 +30,8 @@ func StartSshServer() {
 	pubsub := &psub.Cfg{
 		Logger: logger,
 		PubSub: &psub.PubSubMulticast{
-			Logger: logger,
-			Chan:   make(chan *psub.Subscriber),
+			Logger:   logger,
+			Channels: syncmap.New[string, *psub.Channel](),
 		},
 	}
 

From b2d8f18904531832d8ccf314fbf461223be1dcd3 Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Tue, 10 Sep 2024 19:17:08 -0400
Subject: [PATCH 2/6] Update cli

---
 Dockerfile         | 10 +++++-----
 bouncer/Dockerfile |  2 +-
 go.sum             |  2 --
 imgs/cli.go        |  2 +-
 pubsub/cli.go      | 24 ++++++++++++------------
 5 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index db98d182..2501ddfa 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM --platform=$BUILDPLATFORM golang:1.22 as builder-deps
+FROM --platform=$BUILDPLATFORM golang:1.22 AS builder-deps
 LABEL maintainer="Pico Maintainers <hello@pico.sh>"
 
 WORKDIR /app
@@ -10,7 +10,7 @@ COPY go.* ./
 
 RUN go mod download
 
-FROM builder-deps as builder-web
+FROM builder-deps AS builder-web
 
 COPY . .
 
@@ -25,7 +25,7 @@ ENV GOOS=${TARGETOS} GOARCH=${TARGETARCH}
 
 RUN go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-web ./cmd/${APP}/web
 
-FROM builder-deps as builder-ssh
+FROM builder-deps AS builder-ssh
 
 COPY . .
 
@@ -40,7 +40,7 @@ ENV GOOS=${TARGETOS} GOARCH=${TARGETARCH}
 
 RUN go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-ssh ./cmd/${APP}/ssh
 
-FROM scratch as release-web
+FROM scratch AS release-web
 
 WORKDIR /app
 
@@ -53,7 +53,7 @@ COPY --from=builder-web /app/${APP}/public ./${APP}/public
 
 ENTRYPOINT ["/app/web"]
 
-FROM scratch as release-ssh
+FROM scratch AS release-ssh
 
 WORKDIR /app
 ENV TERM="xterm-256color"
diff --git a/bouncer/Dockerfile b/bouncer/Dockerfile
index f7666e80..5832048c 100644
--- a/bouncer/Dockerfile
+++ b/bouncer/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.22-alpine as builder
+FROM golang:1.22-alpine AS builder
 
 WORKDIR /app
 
diff --git a/go.sum b/go.sum
index fe0d7007..7a2c37fe 100644
--- a/go.sum
+++ b/go.sum
@@ -226,8 +226,6 @@ github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoO
 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9VX6Do3D+w+DansQzkb4NGeyA=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo=
-github.com/picosh/pubsub v0.0.0-20240909042445-92777a8b167b h1:/gGhT8y9rnrv8K9ZJKZYzdWvZcnazl8NGE1DGNrD8HU=
-github.com/picosh/pubsub v0.0.0-20240909042445-92777a8b167b/go.mod h1:FKC8uot+40iXmuDzTfbxYDG5PIc3ghwkmP2iItBKH0I=
 github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161 h1:XKp88wHvv7YQXl4/BfnRCOLmcONTrJK2rE7XMr3gpdw=
 github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg=
diff --git a/imgs/cli.go b/imgs/cli.go
index 8a0f3816..6a7e75ca 100644
--- a/imgs/cli.go
+++ b/imgs/cli.go
@@ -259,7 +259,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				opts.bail(err)
 				return
 			} else if cmd == "sub" {
-				err = pubsub.PubSub.Sub(fmt.Sprintf("%s@%s", user.Name, repoName), &psub.Sub{
+				err = pubsub.PubSub.Sub(fmt.Sprintf("%s/%s", user.Name, repoName), &psub.Sub{
 					ID:     uuid.NewString(),
 					Writer: sesh,
 					Done:   make(chan struct{}),
diff --git a/pubsub/cli.go b/pubsub/cli.go
index c621d843..340070f6 100644
--- a/pubsub/cli.go
+++ b/pubsub/cli.go
@@ -60,11 +60,11 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
 
 // scope channel to user by prefixing name.
 func toChannel(userName, name string) string {
-	return fmt.Sprintf("%s@%s", userName, name)
+	return fmt.Sprintf("%s/%s", userName, name)
 }
 
 func toPublicChannel(name string) string {
-	return fmt.Sprintf("public@%s", name)
+	return fmt.Sprintf("public/%s", name)
 }
 
 var helpStr = `Commands: [pub, sub, ls]
@@ -111,29 +111,29 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				if cmd == "help" {
 					wish.Println(sesh, helpStr)
 				} else if cmd == "ls" {
-					channels := pubsub.PubSub.GetChannels(fmt.Sprintf("%s@", user.Name))
+					channels := pubsub.PubSub.GetChannels(fmt.Sprintf("%s/", user.Name))
 
 					if len(channels) == 0 {
 						wish.Println(sesh, "no pubsub channels found")
 					} else {
-						outputData := "Channel Information\n"
+						outputData := "Channel Information\r\n"
 						for _, channel := range channels {
-							outputData += fmt.Sprintf("- %s:\n", channel.Name)
-							outputData += "\tPubs:\n"
+							outputData += fmt.Sprintf("- %s:\r\n", channel.Name)
+							outputData += "\tPubs:\r\n"
 
 							channel.Pubs.Range(func(I string, J *psub.Pub) bool {
-								outputData += fmt.Sprintf("\t- %s:\n", I)
+								outputData += fmt.Sprintf("\t- %s:\r\n", I)
 								return true
 							})
 
-							outputData += "\tSubs:\n"
+							outputData += "\tSubs:\r\n"
 
 							channel.Subs.Range(func(I string, J *psub.Sub) bool {
-								outputData += fmt.Sprintf("\t- %s:\n", I)
+								outputData += fmt.Sprintf("\t- %s:\r\n", I)
 								return true
 							})
 						}
-						sesh.Write([]byte(outputData))
+						_, _ = sesh.Write([]byte(outputData))
 					}
 				}
 				next(sesh)
@@ -173,7 +173,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 
 				wish.Println(sesh, "sending msg ...")
 				pub := &psub.Pub{
-					ID:     uuid.NewString(),
+					ID:     fmt.Sprintf("%s (%s@%s)", uuid.NewString(), user.Name, sesh.RemoteAddr().String()),
 					Done:   make(chan struct{}),
 					Reader: reader,
 				}
@@ -216,7 +216,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				}
 
 				sub := &psub.Sub{
-					ID:     uuid.NewString(),
+					ID:     fmt.Sprintf("%s (%s@%s)", uuid.NewString(), user.Name, sesh.RemoteAddr().String()),
 					Writer: sesh,
 					Done:   make(chan struct{}),
 					Data:   make(chan []byte),

From b59492637f595f1ab1bde50a3c4dac2b2a18d84c Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Tue, 10 Sep 2024 21:44:24 -0400
Subject: [PATCH 3/6] Update dep

---
 go.mod | 2 +-
 go.sum | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/go.mod b/go.mod
index d6d1b7b8..5c7d6bcf 100644
--- a/go.mod
+++ b/go.mod
@@ -37,7 +37,7 @@ require (
 	github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5
 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
 	github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a
-	github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161
+	github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373
 	github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc
 	github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e
 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
diff --git a/go.sum b/go.sum
index 7a2c37fe..f59bead8 100644
--- a/go.sum
+++ b/go.sum
@@ -226,8 +226,8 @@ github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoO
 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9VX6Do3D+w+DansQzkb4NGeyA=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo=
-github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161 h1:XKp88wHvv7YQXl4/BfnRCOLmcONTrJK2rE7XMr3gpdw=
-github.com/picosh/pubsub v0.0.0-20240910225407-529d97896161/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
+github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373 h1:hYZcA3Rhn2Gp+Rr9BWT3WoE12KX8y+xs3RmiuSUM9JU=
+github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs=

From f18c3b876efb359a36ede132ee777e025850a760 Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Wed, 18 Sep 2024 10:13:21 -0400
Subject: [PATCH 4/6] Updated pubsub ref

---
 go.mod | 2 +-
 go.sum | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/go.mod b/go.mod
index 5c7d6bcf..3370c552 100644
--- a/go.mod
+++ b/go.mod
@@ -37,7 +37,7 @@ require (
 	github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5
 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
 	github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a
-	github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373
+	github.com/picosh/pubsub v0.0.0-20240918141103-977bd6b4c9e2
 	github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc
 	github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e
 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
diff --git a/go.sum b/go.sum
index f59bead8..f41a1f37 100644
--- a/go.sum
+++ b/go.sum
@@ -226,8 +226,8 @@ github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoO
 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9VX6Do3D+w+DansQzkb4NGeyA=
 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo=
-github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373 h1:hYZcA3Rhn2Gp+Rr9BWT3WoE12KX8y+xs3RmiuSUM9JU=
-github.com/picosh/pubsub v0.0.0-20240911013727-cd18ecbb6373/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
+github.com/picosh/pubsub v0.0.0-20240918141103-977bd6b4c9e2 h1:Em/eEiElW3OHKDLzchzJ7m8OOk+yJ8dgc7cH0d0c55Q=
+github.com/picosh/pubsub v0.0.0-20240918141103-977bd6b4c9e2/go.mod h1:vyHLOwIkdaBW+Wmc+3/yRzdnmKwv/oVnKtITHe46w58=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg=
 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs=

From c24792260a8de98bbf53613a8fca03b8511ddfe6 Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Wed, 18 Sep 2024 10:25:23 -0400
Subject: [PATCH 5/6] Added admin listing

---
 pubsub/cli.go | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/pubsub/cli.go b/pubsub/cli.go
index 340070f6..953bd6b3 100644
--- a/pubsub/cli.go
+++ b/pubsub/cli.go
@@ -111,7 +111,12 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 				if cmd == "help" {
 					wish.Println(sesh, helpStr)
 				} else if cmd == "ls" {
-					channels := pubsub.PubSub.GetChannels(fmt.Sprintf("%s/", user.Name))
+					channelFilter := fmt.Sprintf("%s/", user.Name)
+					if handler.DBPool.HasFeatureForUser(user.ID, "admin") {
+						channelFilter = ""
+					}
+
+					channels := pubsub.PubSub.GetChannels(channelFilter)
 
 					if len(channels) == 0 {
 						wish.Println(sesh, "no pubsub channels found")

From fd8e7ba58b2237c820b045aa4dc8b0af36f41f76 Mon Sep 17 00:00:00 2001
From: Antonio Mika <antoniomika@gmail.com>
Date: Wed, 18 Sep 2024 10:33:39 -0400
Subject: [PATCH 6/6] Add more caching to builds

---
 Dockerfile | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 2501ddfa..da4c1f46 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -8,7 +8,9 @@ RUN apt-get install -y git ca-certificates
 
 COPY go.* ./
 
-RUN go mod download
+RUN --mount=type=cache,target=/go/pkg/,rw \
+  --mount=type=cache,target=/root/.cache/,rw \
+  go mod download
 
 FROM builder-deps AS builder-web
 
@@ -23,7 +25,9 @@ ENV LDFLAGS="-s -w"
 
 ENV GOOS=${TARGETOS} GOARCH=${TARGETARCH}
 
-RUN go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-web ./cmd/${APP}/web
+RUN --mount=type=cache,target=/go/pkg/,rw \
+  --mount=type=cache,target=/root/.cache/,rw \
+  go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-web ./cmd/${APP}/web
 
 FROM builder-deps AS builder-ssh
 
@@ -38,7 +42,9 @@ ENV LDFLAGS="-s -w"
 
 ENV GOOS=${TARGETOS} GOARCH=${TARGETARCH}
 
-RUN go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-ssh ./cmd/${APP}/ssh
+RUN --mount=type=cache,target=/go/pkg/,rw \
+  --mount=type=cache,target=/root/.cache/,rw \
+  go build -ldflags "$LDFLAGS" -o /go/bin/${APP}-ssh ./cmd/${APP}/ssh
 
 FROM scratch AS release-web