Skip to content

Commit fcacbcb

Browse files
committed
Code documentation and refactor
1 parent 2c59855 commit fcacbcb

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-26
lines changed

internal/feed/feedmanager.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import (
55
"path"
66
)
77

8+
// FeedManager is the main interface tu feeds and contains the path to ybFeed
9+
// data folder. It is the proper way to get a Feed with proper websocket and
10+
// notifications settings based on current deployment configuration.
811
type FeedManager struct {
912
NotificationSettings *NotificationSettings
1013

1114
path string
1215
websocketManager *WebSocketManager
1316
}
1417

18+
// NewFeedManager returns a FeedManager initialized with the mandatory
19+
// path and websocket manager w.
1520
func NewFeedManager(path string, w *WebSocketManager) *FeedManager {
1621
result := &FeedManager{
1722
path: path,
@@ -20,6 +25,9 @@ func NewFeedManager(path string, w *WebSocketManager) *FeedManager {
2025
return result
2126
}
2227

28+
// GetFeed returns the Feed with name feedName. Authentication is not vaidates
29+
// Be careful when using GetFeed that the result isn't returned to the browser
30+
// directly. It should ony be used for internal methods
2331
func (m *FeedManager) GetFeed(feedName string) (*Feed, error) {
2432
feedPath := path.Join(m.path, feedName)
2533

@@ -34,6 +42,9 @@ func (m *FeedManager) GetFeed(feedName string) (*Feed, error) {
3442
return result, nil
3543
}
3644

45+
// GetFeedWithAuth returns the Feed feedName if the secret is valid,
46+
// otherwise it returns an error. GetFeedWithAuth should always be user
47+
// when fetching a Feed for end user consumption
3748
func (m *FeedManager) GetFeedWithAuth(feedName string, secret string) (*Feed, error) {
3849
result, err := m.GetFeed(feedName)
3950

internal/feed/pushnotifications.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import (
1111

1212
var pnL = yblog.NewYBLogger("push", []string{"DEBUG", "DEBUG_NOTIFICATIONS"})
1313

14+
// sendPushNotification notifies all subscribed browser that an item has been
15+
// added
1416
func (f *Feed) sendPushNotification() error {
15-
// Send push notifications
17+
// Check that notification settings are present
1618
if f.NotificationSettings == nil {
1719
pnL.Logger.Debug("Feed has no notifications settings")
1820
return nil
1921
}
22+
23+
// For each subscription we send the notification
2024
for _, subscription := range f.Config.Subscriptions {
2125
pnL.Logger.Debug("Sending push notification", slog.String("endpoint", subscription.Endpoint))
2226
resp, _ := webpush.SendNotification([]byte(fmt.Sprintf("New item posted to feed %s", f.Name())), &subscription, &webpush.Options{

internal/feed/websocket.go

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"net/http"
77
"strings"
88

9-
"github.com/gorilla/websocket"
109
ws "github.com/gorilla/websocket"
1110
"github.com/ybizeul/ybfeed/internal/utils"
1211
"github.com/ybizeul/ybfeed/pkg/yblog"
@@ -15,16 +14,17 @@ import (
1514

1615
var wsL = yblog.NewYBLogger("push", []string{"DEBUG", "DEBUG_WEBSOCKET"})
1716

17+
// upgrader is used to upgrade a connection to a websocket
18+
var upgrader = ws.Upgrader{} // use default options
19+
20+
// FeedSockets maintains a list of active websockets for a specific feed
21+
// designated by feedName
1822
type FeedSockets struct {
1923
feedName string
2024
websockets []*ws.Conn
2125
}
2226

23-
type FeedNotification struct {
24-
Action string `json:"action"`
25-
Item PublicFeedItem `json:"item"`
26-
}
27-
27+
// RemoveConn removes the websocket c from the list of active websockets
2828
func (fs *FeedSockets) RemoveConn(c *ws.Conn) {
2929
wsL.Logger.Debug("Removing connection",
3030
slog.Int("count", len(fs.websockets)),
@@ -40,22 +40,32 @@ func (fs *FeedSockets) RemoveConn(c *ws.Conn) {
4040
}
4141
}
4242

43+
// FeedNotification is used to marshall notification information message
44+
// to the push service
45+
type FeedNotification struct {
46+
Action string `json:"action"`
47+
Item PublicFeedItem `json:"item"`
48+
}
49+
50+
// WebSocketManager bridges a FeedManager with a FeedSockets struct
4351
type WebSocketManager struct {
4452
FeedSockets []*FeedSockets
4553
FeedManager *FeedManager
4654
}
4755

56+
// NewWebSocketManager creates a new WebSocketManager. There is typically one
57+
// WebSocketManager per ybFeed deployment.
4858
func NewWebSocketManager(fm *FeedManager) *WebSocketManager {
4959
return &WebSocketManager{
5060
FeedManager: fm,
5161
}
5262
}
5363

54-
var upgrader = websocket.Upgrader{} // use default options
55-
64+
// FeedSocketsForFeed returns the FeedSockets for feed feedName
5665
func (m *WebSocketManager) FeedSocketsForFeed(feedName string) *FeedSockets {
5766
wsL.Logger.Debug("Searching FeedSockets", slog.Int("count", len(m.FeedSockets)), slog.String("feedName", feedName))
5867

68+
// Loop through all FeedSockets to find the one for this feed
5969
for _, fs := range m.FeedSockets {
6070
if fs.feedName == feedName {
6171
return fs
@@ -64,29 +74,44 @@ func (m *WebSocketManager) FeedSocketsForFeed(feedName string) *FeedSockets {
6474
return nil
6575
}
6676

77+
// RunSocketForFeed promotes an HTTP connection to a websocket and starts
78+
// waiting for data. This function is blocking and typically runs from
79+
// a http handler.
6780
func (m *WebSocketManager) RunSocketForFeed(feedName string, w http.ResponseWriter, r *http.Request) {
68-
c, err := upgrader.Upgrade(w, r, nil)
69-
81+
// Check if we already have websockets for this feed
7082
feedSockets := m.FeedSocketsForFeed(feedName)
7183

72-
if feedSockets == nil {
84+
if feedSockets == nil { // No, then we create a new FeedSockets
7385
wsL.Logger.Debug("Adding FeedSockets", slog.Int("count_before", len(m.FeedSockets)), slog.String("feedName", feedName))
7486
feedSockets = &FeedSockets{
7587
feedName: feedName,
7688
}
7789
m.FeedSockets = append(m.FeedSockets, feedSockets)
7890
}
7991

80-
wsL.Logger.Debug("Adding connection", slog.Int("count", len(feedSockets.websockets)))
92+
c, err := upgrader.Upgrade(w, r, nil)
93+
if err != nil {
94+
utils.CloseWithCodeAndMessage(w, 500, "Unable to upgrade WebSocket")
95+
}
96+
8197
feedSockets.websockets = append(feedSockets.websockets, c)
82-
wsL.Logger.Debug("Added connection", slog.Int("count", len(feedSockets.websockets)))
8398

84-
wsL.Logger.Debug("WebSocket added", slog.Int("array size", len(feedSockets.websockets)))
99+
secret, _ := utils.GetSecret(r)
100+
101+
f, err := m.FeedManager.GetFeedWithAuth(feedName, secret)
85102

86103
if err != nil {
87-
utils.CloseWithCodeAndMessage(w, 500, "Unable to upgrade WebSocket")
104+
switch {
105+
case errors.Is(err, FeedErrorNotFound):
106+
utils.CloseWithCodeAndMessage(w, 404, "feed not found")
107+
case errors.Is(err, FeedErrorInvalidSecret):
108+
utils.CloseWithCodeAndMessage(w, 401, "invalid secret")
109+
case errors.Is(err, FeedErrorIncorrectSecret):
110+
utils.CloseWithCodeAndMessage(w, 401, "incorrect secret")
111+
default:
112+
utils.CloseWithCodeAndMessage(w, 500, err.Error())
113+
}
88114
}
89-
secret, _ := utils.GetSecret(r)
90115

91116
defer func() {
92117
feedSockets.RemoveConn(c)
@@ -102,15 +127,6 @@ func (m *WebSocketManager) RunSocketForFeed(feedName string, w http.ResponseWrit
102127
}
103128
switch strings.TrimSpace(string(message)) {
104129
case "feed":
105-
f, err := m.FeedManager.GetFeed(feedName)
106-
if ferr := f.IsSecretValid(secret); err != nil {
107-
if errors.Is(ferr, FeedErrorInvalidSecret) {
108-
utils.CloseWithCodeAndMessage(w, 401, "invalid secret")
109-
}
110-
}
111-
if err != nil {
112-
utils.CloseWithCodeAndMessage(w, 500, err.Error())
113-
}
114130
pf, err := f.Public()
115131
if err != nil {
116132
utils.CloseWithCodeAndMessage(w, 500, err.Error())

0 commit comments

Comments
 (0)