Created func for minimum spec for rss and article structs, thereby crushing an annoying bug that was caused by not initializing channels but waiting for messages to go through them

This commit is contained in:
Jason Streifling 2024-03-02 00:28:42 +01:00
parent 4e2cae74bb
commit 2da17014e4
4 changed files with 70 additions and 46 deletions

View File

@ -1,6 +1,7 @@
package data package data
import ( import (
"sync"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
@ -16,14 +17,25 @@ type Article struct {
} }
type ArticleList struct { type ArticleList struct {
addCh chan *Article addCh chan *Article
delCh chan uuid.UUID delCh chan uuid.UUID
retCh chan *Article retCh chan *Article
listCh chan []Article getCh chan []Article
list []*Article list []*Article
wg sync.WaitGroup
}
func minArticleList() *ArticleList {
return &ArticleList{
addCh: make(chan *Article),
delCh: make(chan uuid.UUID),
retCh: make(chan *Article),
getCh: make(chan []Article),
}
} }
func (l *ArticleList) start() { func (l *ArticleList) start() {
l.wg.Done()
for { for {
select { select {
case article := <-l.addCh: case article := <-l.addCh:
@ -35,7 +47,7 @@ func (l *ArticleList) start() {
l.retCh <- article l.retCh <- article
} }
} }
case l.listCh <- func() []Article { case l.getCh <- func() []Article {
var list []Article var list []Article
for _, article := range l.list { for _, article := range l.list {
list = append(list, *article) list = append(list, *article)
@ -47,14 +59,13 @@ func (l *ArticleList) start() {
} }
func NewArticleList() *ArticleList { func NewArticleList() *ArticleList {
list := &ArticleList{ list := minArticleList()
addCh: make(chan *Article), list.list = []*Article{}
delCh: make(chan uuid.UUID),
retCh: make(chan *Article), list.wg.Add(1)
listCh: make(chan []Article),
list: []*Article{},
}
go list.start() go list.start()
list.wg.Wait()
return list return list
} }
@ -71,6 +82,6 @@ func (l *ArticleList) Release(uuid uuid.UUID) (*Article, bool) {
return article, true return article, true
} }
func (l *ArticleList) List() []Article { func (l *ArticleList) Get() []Article {
return <-l.listCh return <-l.getCh
} }

View File

@ -4,57 +4,74 @@ import (
"encoding/gob" "encoding/gob"
"fmt" "fmt"
"os" "os"
"sync"
"github.com/gorilla/feeds" "github.com/gorilla/feeds"
) )
type Feed struct { type Feed struct {
addCh chan *feeds.Item addCh chan *feeds.Item
openCh chan feeds.Feed setCh chan feeds.Feed
saveCh chan feeds.Feed getCh chan feeds.Feed
showCh chan feeds.Feed feed feeds.Feed
feed feeds.Feed wg sync.WaitGroup
}
func minFeed() *Feed {
return &Feed{
addCh: make(chan *feeds.Item),
setCh: make(chan feeds.Feed),
getCh: make(chan feeds.Feed),
}
} }
func (f *Feed) start() { func (f *Feed) start() {
f.wg.Done()
for { for {
select { select {
case item := <-f.addCh: case item := <-f.addCh:
f.feed.Items = append(f.feed.Items, item) f.feed.Items = append(f.feed.Items, item)
case f.saveCh <- f.feed: case f.getCh <- f.feed:
case tmpFeed := <-f.openCh: case f.feed = <-f.setCh:
f.feed = tmpFeed
case f.showCh <- f.feed:
} }
} }
} }
func NewFeed(title, link, desc string) *Feed { func NewFeed(title, link, desc string) *Feed {
feed := &Feed{ feed := minFeed()
addCh: make(chan *feeds.Item), feed.feed = feeds.Feed{
openCh: make(chan feeds.Feed), Title: title,
saveCh: make(chan feeds.Feed), Link: &feeds.Link{Href: link},
showCh: make(chan feeds.Feed), Description: desc,
feed: feeds.Feed{
Title: title,
Link: &feeds.Link{Href: link},
Description: desc,
},
} }
feed.wg.Add(1)
go feed.start() go feed.start()
feed.wg.Wait()
return feed return feed
} }
func OpenFeed(filename string) (*Feed, error) { func (f *Feed) Get() feeds.Feed {
feed := new(Feed) return <-f.getCh
go feed.start() }
func (f *Feed) Set(feed feeds.Feed) {
f.setCh <- feed
}
func OpenFeed(filename string) (*Feed, error) {
file, err := os.Open(filename) file, err := os.Open(filename)
if err != nil { if err != nil {
return nil, fmt.Errorf("error opening file %v: %v", filename, err) return nil, fmt.Errorf("error opening file %v: %v", filename, err)
} }
defer file.Close() defer file.Close()
feed := minFeed()
feed.wg.Add(1)
go feed.start()
feed.wg.Wait()
decoder := gob.NewDecoder(file) decoder := gob.NewDecoder(file)
tmpFeed := new(feeds.Feed) tmpFeed := new(feeds.Feed)
err = decoder.Decode(tmpFeed) err = decoder.Decode(tmpFeed)
@ -62,7 +79,7 @@ func OpenFeed(filename string) (*Feed, error) {
return nil, fmt.Errorf("error decoding file %v: %v", filename, err) return nil, fmt.Errorf("error decoding file %v: %v", filename, err)
} }
feed.openCh <- *tmpFeed feed.Set(*tmpFeed)
return feed, nil return feed, nil
} }
@ -75,7 +92,7 @@ func (f *Feed) Save(filename string) error {
defer file.Close() defer file.Close()
encoder := gob.NewEncoder(file) encoder := gob.NewEncoder(file)
feed := <-f.saveCh feed := f.Get()
err = encoder.Encode(feed) err = encoder.Encode(feed)
if err != nil { if err != nil {
return fmt.Errorf("error encoding file %v: %v", filename, err) return fmt.Errorf("error encoding file %v: %v", filename, err)
@ -87,7 +104,3 @@ func (f *Feed) Save(filename string) error {
func (f *Feed) Add(i *feeds.Item) { func (f *Feed) Add(i *feeds.Item) {
f.addCh <- i f.addCh <- i
} }
func (f *Feed) Show() feeds.Feed {
return <-f.showCh
}

View File

@ -60,7 +60,7 @@ func FinishArticle(l *data.ArticleList) http.HandlerFunc {
func ShowUnpublishedArticles(l *data.ArticleList) http.HandlerFunc { func ShowUnpublishedArticles(l *data.ArticleList) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
template.Must(template.ParseFiles("web/templates/unpublished-articles.html")).ExecuteTemplate(w, "page-content", l.List) template.Must(template.ParseFiles("web/templates/unpublished-articles.html")).ExecuteTemplate(w, "page-content", l.Get())
} }
} }
@ -73,7 +73,7 @@ func ReviewArticle(l *data.ArticleList) http.HandlerFunc {
return return
} }
for _, article := range l.List() { for _, article := range l.Get() {
if article.UUID == uuid { if article.UUID == uuid {
template.Must(template.ParseFiles("web/templates/to-be-published.html")).ExecuteTemplate(w, "page-content", article) template.Must(template.ParseFiles("web/templates/to-be-published.html")).ExecuteTemplate(w, "page-content", article)
return return

View File

@ -10,7 +10,7 @@ import (
func ShowRSS(f *data.Feed) http.HandlerFunc { func ShowRSS(f *data.Feed) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
feed := f.Show() feed := f.Get()
rss, err := feed.ToRss() rss, err := feed.ToRss()
if err != nil { if err != nil {
log.Println(err) log.Println(err)