Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace sqlite database with append only file #7

Merged
merged 1 commit into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.DS_Store
.env
go-talks
talks.db
main
gin-bin
backups
config.toml
config.toml
*.db*
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ go-talks (Or more commonly known as just Talks) is an app to manage talks at COS
- /posts directory supports rendering pre-written markdown files
- Image caching/proxying
- Create future talks and view historic talks
- Backed by SQLITE database
- Backed by an append only log database

## Endpoints

Expand All @@ -27,3 +27,4 @@ go-talks (Or more commonly known as just Talks) is an app to manage talks at COS
| GET | /img/{id} | Image proxy |
| GET | /health | Indicates how many active connections there are |
| GET | /ws | Websocket endpoint |

37 changes: 0 additions & 37 deletions backup.go

This file was deleted.

103 changes: 84 additions & 19 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,58 @@ const (
DELETE
// AUTH communicates authentication request/response
AUTH
// SYNC requests a sync of the talks
SYNC
)

// Message is the format of messages sent between the client and server
// Since go doesn't have the strongest type system we pack every message
// into a single struct
type Message struct {
Type MessageType `json:"type"`
ID uint32 `json:"id,omitempty"`
Password string `json:"password,omitempty"`
Name string `json:"name,omitempty"`
Talktype *TalkType `json:"talktype,omitempty"`
Description string `json:"description,omitempty"`
Week string `json:"week,omitempty"`
Type MessageType `json:"type"`
New *NewMessage `json:"new,omitempty"`
Hide *HideMessage `json:"hide,omitempty"`
Del *DeleteMessage `json:"delete,omitempty"`
Auth *AuthMessage `json:"auth,omitempty"`
Sync *SyncMessage `json:"sync,omitempty"`
}

// NewMessage gives the client all the information needed to add a new talk to
// the page
type NewMessage struct {
ID uint32 `json:"id"`
Name string `json:"name"`
Talktype TalkType `json:"talktype"`
Description string `json:"description"`
Week string `json:"week"`
}

// HideMessage gives the client the ID of the talk to hide
type HideMessage struct {
ID uint32 `json:"id"`
}

// DeleteMessage gives the client the ID of the talk to delete
type DeleteMessage struct {
ID uint32 `json:"id"`
}

// AuthMessage gives the client the password to authenticate
type AuthMessage struct {
Password string `json:"password"`
}

// SyncMessage starts and caps off a sync
type SyncMessage struct {
Week string `json:"week"`
}

func authenticatedMessage(b bool) []byte {
if b {
return []byte("{\"type\": 3, \"status\": true}")
return []byte("{\"type\": 3, \"auth\": {\"status\": true}}")
}

return []byte("{\"type\": 3, \"status\": false}")
return []byte("{\"type\": 3, \"auth\": {\"status\": false}}")
}

func (c *Client) read() {
Expand All @@ -73,21 +104,54 @@ func (c *Client) read() {
var message Message
err = json.Unmarshal(raw, &message)
if err != nil {
// Print the message and continue
log.Printf("[WARN] %v", err)
continue
}

// Handle authentication without consulting the hub
if message.Type == AUTH {
switch message.Type {
case NEW, HIDE, DELETE:
// NEW, HIDE, and DELETE need to be serialized through the hub
hub.broadcast <- message
case AUTH:
// AUTH is handled without having to contact the hub
log.Printf("[INFO] Client %v is trying to authenticate", c.conn.RemoteAddr())

c.auth = message.Password == config.Password
c.send <- authenticatedMessage(c.auth)

continue
c.send <- authenticatedMessage(message.Auth.Password == config.Password)
case SYNC:
// SYNC messages don't need to be serialized, go straight to the db
log.Printf("[INFO] Client %v is requesting a sync", c.conn.RemoteAddr())
for _, talk := range talks.AllTalks(message.Sync.Week) {
var msg Message
if talk.Hidden {
// Send a hide message
msg = Message{
Type: HIDE,
Hide: &HideMessage{
ID: talk.ID,
},
}
} else {
// Send a create message
msg = Message{
Type: NEW,
New: &NewMessage{
ID: talk.ID,
Name: talk.Name,
Talktype: talk.Type,
Description: talk.Description,
Week: talk.Week,
},
}
}
// Send the message
raw, _ := json.Marshal(msg)
c.send <- raw
}
raw, _ := json.Marshal(message)
c.send <- raw
default:
log.Printf("[WARN] Client %v sent an invalid message type", c.conn.RemoteAddr())
}

// Forward all other message to be processed and broadcasted to other client
hub.broadcast <- message
}
}

Expand All @@ -103,6 +167,7 @@ func (c *Client) write() {
select {
case message, ok := <-c.send:
if !ok {
log.Println("[INFO] Closing connection")
return
}

Expand Down
Loading