From 4e2cae74bbccbc3c5654162c9754a7246e4580f5 Mon Sep 17 00:00:00 2001 From: Jason Streifling Date: Fri, 1 Mar 2024 21:01:38 +0100 Subject: [PATCH] Changed articles and rss to channels --- cmd/data/articles.go | 73 ++++++++++++++++++++++++++++++++------------ cmd/data/rss.go | 53 ++++++++++++++++++++++++-------- cmd/ui/articles.go | 4 +-- cmd/ui/rss.go | 3 +- main.go | 2 +- 5 files changed, 99 insertions(+), 36 deletions(-) diff --git a/cmd/data/articles.go b/cmd/data/articles.go index ef7ab3e..a174dc1 100644 --- a/cmd/data/articles.go +++ b/cmd/data/articles.go @@ -1,7 +1,6 @@ package data import ( - "sync" "time" "github.com/google/uuid" @@ -12,30 +11,66 @@ type Article struct { Created time.Time Desc string Content string + Tags []string UUID uuid.UUID } type ArticleList struct { - List []Article - sync.Mutex + addCh chan *Article + delCh chan uuid.UUID + retCh chan *Article + listCh chan []Article + list []*Article } -func (l *ArticleList) Add(a Article) { - l.Lock() - l.List = append(l.List, a) - l.Unlock() -} - -func (l *ArticleList) Release(uuid uuid.UUID) (Article, bool) { - l.Lock() - for i, article := range l.List { - if article.UUID == uuid { - foo := l.List[i] - l.List = append(l.List[:i], l.List[i+1:]...) - l.Unlock() - return foo, true +func (l *ArticleList) start() { + for { + select { + case article := <-l.addCh: + l.list = append(l.list, article) + case uuid := <-l.delCh: + for i, article := range l.list { + if article.UUID == uuid { + l.list = append(l.list[:i], l.list[i+1:]...) + l.retCh <- article + } + } + case l.listCh <- func() []Article { + var list []Article + for _, article := range l.list { + list = append(list, *article) + } + return list + }(): } } - l.Unlock() - return Article{}, false +} + +func NewArticleList() *ArticleList { + list := &ArticleList{ + addCh: make(chan *Article), + delCh: make(chan uuid.UUID), + retCh: make(chan *Article), + listCh: make(chan []Article), + list: []*Article{}, + } + go list.start() + return list +} + +func (l *ArticleList) Add(a *Article) { + l.addCh <- a +} + +func (l *ArticleList) Release(uuid uuid.UUID) (*Article, bool) { + l.delCh <- uuid + article := <-l.retCh + if article == nil { + return nil, false + } + return article, true +} + +func (l *ArticleList) List() []Article { + return <-l.listCh } diff --git a/cmd/data/rss.go b/cmd/data/rss.go index 3d92223..c34b1e7 100644 --- a/cmd/data/rss.go +++ b/cmd/data/rss.go @@ -4,40 +4,66 @@ import ( "encoding/gob" "fmt" "os" - "sync" "github.com/gorilla/feeds" ) type Feed struct { - feeds.Feed - sync.Mutex + addCh chan *feeds.Item + openCh chan feeds.Feed + saveCh chan feeds.Feed + showCh chan feeds.Feed + feed feeds.Feed +} + +func (f *Feed) start() { + for { + select { + case item := <-f.addCh: + f.feed.Items = append(f.feed.Items, item) + case f.saveCh <- f.feed: + case tmpFeed := <-f.openCh: + f.feed = tmpFeed + case f.showCh <- f.feed: + } + } } func NewFeed(title, link, desc string) *Feed { - return &Feed{ - Feed: feeds.Feed{ + feed := &Feed{ + addCh: make(chan *feeds.Item), + openCh: make(chan feeds.Feed), + saveCh: make(chan feeds.Feed), + showCh: make(chan feeds.Feed), + feed: feeds.Feed{ Title: title, Link: &feeds.Link{Href: link}, Description: desc, }, } + go feed.start() + return feed } func OpenFeed(filename string) (*Feed, error) { + feed := new(Feed) + go feed.start() + file, err := os.Open(filename) if err != nil { return nil, fmt.Errorf("error opening file %v: %v", filename, err) } defer file.Close() - feed := new(Feed) decoder := gob.NewDecoder(file) - err = decoder.Decode(&feed.Feed) + tmpFeed := new(feeds.Feed) + err = decoder.Decode(tmpFeed) if err != nil { return nil, fmt.Errorf("error decoding file %v: %v", filename, err) } + feed.openCh <- *tmpFeed + return feed, nil } @@ -49,9 +75,8 @@ func (f *Feed) Save(filename string) error { defer file.Close() encoder := gob.NewEncoder(file) - f.Lock() - err = encoder.Encode(f.Feed) - f.Unlock() + feed := <-f.saveCh + err = encoder.Encode(feed) if err != nil { return fmt.Errorf("error encoding file %v: %v", filename, err) } @@ -60,7 +85,9 @@ func (f *Feed) Save(filename string) error { } func (f *Feed) Add(i *feeds.Item) { - f.Lock() - f.Items = append(f.Items, i) - f.Unlock() + f.addCh <- i +} + +func (f *Feed) Show() feeds.Feed { + return <-f.showCh } diff --git a/cmd/ui/articles.go b/cmd/ui/articles.go index 2c1bd4a..f08ee4e 100644 --- a/cmd/ui/articles.go +++ b/cmd/ui/articles.go @@ -25,7 +25,7 @@ func WriteArticle() http.HandlerFunc { func FinishArticle(l *data.ArticleList) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - article := data.Article{} + article := new(data.Article) var err error article.Title, err = data.ConvertToPlain(r.PostFormValue("editor-title")) @@ -73,7 +73,7 @@ func ReviewArticle(l *data.ArticleList) http.HandlerFunc { return } - for _, article := range l.List { + for _, article := range l.List() { if article.UUID == uuid { template.Must(template.ParseFiles("web/templates/to-be-published.html")).ExecuteTemplate(w, "page-content", article) return diff --git a/cmd/ui/rss.go b/cmd/ui/rss.go index 75c6479..1b373c1 100644 --- a/cmd/ui/rss.go +++ b/cmd/ui/rss.go @@ -8,8 +8,9 @@ import ( "streifling.com/jason/cpolis/cmd/data" ) -func ShowRSS(feed *data.Feed) http.HandlerFunc { +func ShowRSS(f *data.Feed) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + feed := f.Show() rss, err := feed.ToRss() if err != nil { log.Println(err) diff --git a/main.go b/main.go index 5217125..56eb4d5 100644 --- a/main.go +++ b/main.go @@ -31,7 +31,7 @@ func main() { "Freiheit, Gleichheit, Brüderlichkeit, Toleranz und Humanität") } - articleList := new(data.ArticleList) + articleList := data.NewArticleList() mux := http.NewServeMux() mux.Handle("/web/static/", http.StripPrefix("/web/static/", http.FileServer(http.Dir("web/static/"))))