Skip to content

Commit

Permalink
New: code refactor, cache impl, logger fix (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Icerzack authored May 17, 2024
1 parent 550fab6 commit d7e3497
Show file tree
Hide file tree
Showing 19 changed files with 308 additions and 111 deletions.
4 changes: 2 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ linters-settings:
sections:
- standard
- default
- prefix(github.com/Icerzack/excalidraw-ws-go)
- prefix(github.com/Icerzack/excaliroom)

godot:
scope: declarations
exclude:
- '^ @'

goimports:
local-prefixes: github.com/Icerzack/excalidraw-ws-go
local-prefixes: github.com/Icerzack/excaliroom

lll:
tab-width: 4
Expand Down
21 changes: 15 additions & 6 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import (
"fmt"
"os"

"go.uber.org/zap"
"gopkg.in/yaml.v3"
)

type Config struct {
Apps struct {
LogLevel string `yaml:"log_level"`
Rest struct {
Rest struct {
Port int `yaml:"port"`
Validation struct {
JWTHeaderName string `yaml:"jwt_header_name"`
Expand All @@ -20,6 +18,10 @@ type Config struct {
} `yaml:"validation"`
} `yaml:"rest"`
} `yaml:"apps"`
Logging struct {
Level string `yaml:"level"`
WriteToFile bool `yaml:"write_to_file"`
} `yaml:"logging"`
Storage struct {
Users struct {
Type string `yaml:"type"`
Expand All @@ -34,20 +36,27 @@ type Config struct {
RedisDB int `yaml:"redis_db"`
} `yaml:"rooms"`
} `yaml:"storage"`
Cache struct {
Type string `yaml:"type"`
TTL int64 `yaml:"ttl"`
RedisAddress string `yaml:"redis_address"`
RedisPassword string `yaml:"redis_password"`
RedisDB int `yaml:"redis_db"`
} `yaml:"cache"`
}

func ParseConfig(path string, logger *zap.Logger) (*Config, error) {
func ParseConfig(path string) (*Config, error) {
file, err := os.Open(path)
if err != nil {
logger.Error("Failed to open config file", zap.Error(err))
fmt.Println("error opening config file Path:", path, err)
return nil, fmt.Errorf("error opening file %w", err)
}
defer file.Close()

var config Config
err = yaml.NewDecoder(file).Decode(&config)
if err != nil {
logger.Error("Failed to decode config file", zap.Error(err))
fmt.Println("error decoding config file", err)
return nil, fmt.Errorf("error decoding file %w", err)
}

Expand Down
9 changes: 8 additions & 1 deletion config-example.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
apps:
log_level: "DEBUG"
rest:
port: 8080
validation:
jwt_header_name: "<YOUR_JWT_HEADER_NAME>"
jwt_validation_url: "<YOUR_JWT_VALIDATION_URL>"
board_validation_url: "<YOUR_BOARD_VALIDATION_URL>"

logging:
level: "DEBUG"
write_to_file: false

storage:
users:
type: "in-memory"
rooms:
type: "in-memory"

cache:
type: "in-memory"
ttl: 300
5 changes: 3 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ version: "3.8"

services:
app:
image: icerzack/excaliroom:latest
platform: linux/amd64
build:
context: .
dockerfile: build/Dockerfile
environment:
- CONFIG_PATH=config.yaml
ports:
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module github.com/Icerzack/excalidraw-ws-go
module github.com/Icerzack/excaliroom

go 1.21

require (
github.com/go-chi/chi v1.5.5
github.com/go-chi/chi/v5 v5.0.12
github.com/gorilla/websocket v1.5.1
go.uber.org/zap v1.27.0
gopkg.in/yaml.v3 v3.0.1
)

require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -14,8 +14,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
7 changes: 7 additions & 0 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package cache

type Cache interface {
Set(key string, value interface{}) error
Get(key string) (interface{}, error)
SetWithTTL(key string, value interface{}, ttl int64) error
}
62 changes: 62 additions & 0 deletions internal/cache/inmemory/inmemory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package inmemory

import (
"sync"
"time"

"go.uber.org/zap"
)

type Item struct {
Value interface{}
Expiration int64
}

type Cache struct {
mu sync.RWMutex
items map[string]*Item
logger *zap.Logger
}

func NewCache(logger *zap.Logger) *Cache {
return &Cache{
items: make(map[string]*Item),
logger: logger,
}
}

func (c *Cache) Set(key string, value interface{}) error {
c.mu.Lock()
defer c.mu.Unlock()

c.items[key] = &Item{
Value: value,
}
c.logger.Debug("User added to cache", zap.String("key", key))
return nil
}

func (c *Cache) SetWithTTL(key string, value interface{}, ttl int64) error {
c.mu.Lock()
defer c.mu.Unlock()

c.items[key] = &Item{
Value: value,
Expiration: time.Now().UnixNano() + ttl*int64(time.Second),
}
c.logger.Debug("User added to cache", zap.String("key", key))
return nil
}

func (c *Cache) Get(key string) (interface{}, error) {
c.mu.RLock()
defer c.mu.RUnlock()

item, ok := c.items[key]
if !ok || item.Expiration < time.Now().UnixNano() {
c.logger.Debug("User not found in cache", zap.String("key", key))
return nil, nil
}

return item.Value, nil
}
12 changes: 5 additions & 7 deletions internal/room/room.go → internal/models/room.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package room
package models

import (
"crypto/rand"
"sync"

"github.com/Icerzack/excalidraw-ws-go/internal/user"
)

type Room struct {
Expand All @@ -15,7 +13,7 @@ type Room struct {
BoardID string

// Users is a map of users in the room
Users []*user.User
Users []*User

// LeaderID is the unique identifier of the leader of the room
LeaderID string
Expand All @@ -37,14 +35,14 @@ func NewRoom(boardID string) *Room {
return &Room{
ID: generateRandomID(),
BoardID: boardID,
Users: make([]*user.User, 0),
Users: make([]*User, 0),
LeaderID: "0",
mtx: &sync.RWMutex{},
RoomMutex: &sync.Mutex{},
}
}

func (r *Room) AddUser(newUser *user.User) {
func (r *Room) AddUser(newUser *User) {
// Add user to the room
r.mtx.Lock()
defer r.mtx.Unlock()
Expand All @@ -63,7 +61,7 @@ func (r *Room) RemoveUser(userID string) {
}
}

func (r *Room) GetUsers() []*user.User {
func (r *Room) GetUsers() []*User {
// Get users of the room
r.mtx.RLock()
defer r.mtx.RUnlock()
Expand Down
2 changes: 1 addition & 1 deletion internal/user/user.go → internal/models/user.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package user
package models

import "github.com/gorilla/websocket"

Expand Down
6 changes: 6 additions & 0 deletions internal/rest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ type Config struct {
// RoomsStorageType is the type of the storage that will be used
RoomsStorageType string

// CacheType is the type of the cache that will be used
CacheType string

// CacheTTL is the time to live of the cache
CacheTTL int64

Logger *zap.Logger
}
39 changes: 30 additions & 9 deletions internal/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import (
"net/http"
"strconv"

"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"go.uber.org/zap"

"github.com/Icerzack/excalidraw-ws-go/internal/rest/ws"
"github.com/Icerzack/excalidraw-ws-go/internal/storage/room"
inmemRoom "github.com/Icerzack/excalidraw-ws-go/internal/storage/room/inmemory"
"github.com/Icerzack/excalidraw-ws-go/internal/storage/user"
inmemUser "github.com/Icerzack/excalidraw-ws-go/internal/storage/user/inmemory"
"github.com/Icerzack/excaliroom/internal/cache"
"github.com/Icerzack/excaliroom/internal/cache/inmemory"
"github.com/Icerzack/excaliroom/internal/rest/ws"
"github.com/Icerzack/excaliroom/internal/storage/room"
inmemRoom "github.com/Icerzack/excaliroom/internal/storage/room/inmemory"
"github.com/Icerzack/excaliroom/internal/storage/user"
inmemUser "github.com/Icerzack/excaliroom/internal/storage/user/inmemory"
)

type Rest struct {
Expand Down Expand Up @@ -41,9 +43,13 @@ func (rest *Rest) Start() {

// Define the /ws endpoint
usersStorage, roomsStorage := rest.defineStorage()
selectedCache := rest.defineCache()

wsServer := ws.NewWebSocketHandler(
usersStorage,
roomsStorage,
selectedCache,
rest.config.CacheTTL,
rest.config.JwtHeaderName,
rest.config.JwtValidationURL,
rest.config.BoardValidationURL,
Expand All @@ -68,9 +74,9 @@ func (rest *Rest) Stop() {
}
}

func (rest *Rest) defineStorage() (*inmemUser.Storage, *inmemRoom.Storage) {
var usersStorage *inmemUser.Storage
var roomsStorage *inmemRoom.Storage
func (rest *Rest) defineStorage() (user.Storage, room.Storage) {
var usersStorage user.Storage
var roomsStorage room.Storage

switch rest.config.UsersStorageType {
case user.InMemoryStorageType:
Expand All @@ -91,3 +97,18 @@ func (rest *Rest) defineStorage() (*inmemUser.Storage, *inmemRoom.Storage) {

return usersStorage, roomsStorage
}

func (rest *Rest) defineCache() cache.Cache {
var c cache.Cache

switch rest.config.CacheType {
case room.InMemoryStorageType:
rest.config.Logger.Info("Using in-memory cache")
c = inmemory.NewCache(rest.config.Logger)
default:
rest.config.Logger.Info("Using in-memory cache")
c = inmemory.NewCache(rest.config.Logger)
}

return c
}
Loading

0 comments on commit d7e3497

Please sign in to comment.