remove more channels to prevent deadlocks
This commit is contained in:
parent
be7efb24cd
commit
42cc7f26c4
@ -17,9 +17,6 @@ type CacheInterface interface {
|
||||
|
||||
Start()
|
||||
Close()
|
||||
|
||||
GetThreadChan() chan ArticleEntry
|
||||
GetGroupChan() chan groupRegenRequest
|
||||
GetHandler() http.Handler
|
||||
|
||||
SetRequireCaptcha(required bool)
|
||||
|
@ -189,8 +189,6 @@ type httpFrontend struct {
|
||||
attachments bool
|
||||
|
||||
prefix string
|
||||
regenThreadChan chan ArticleEntry
|
||||
regenGroupChan chan groupRegenRequest
|
||||
|
||||
store *sessions.CookieStore
|
||||
|
||||
@ -224,15 +222,14 @@ func (self httpFrontend) AllowNewsgroup(group string) bool {
|
||||
func (self *httpFrontend) Regen(msg ArticleEntry) {
|
||||
self.cache.Regen(msg)
|
||||
}
|
||||
func (self *httpFrontend) RegenerateBoard(board string) {
|
||||
self.cache.RegenerateBoard(board)
|
||||
}
|
||||
|
||||
func (self httpFrontend) regenAll() {
|
||||
self.cache.RegenAll()
|
||||
}
|
||||
|
||||
func (self *httpFrontend) regenerateBoard(group string) {
|
||||
self.cache.RegenerateBoard(group)
|
||||
}
|
||||
|
||||
func (self httpFrontend) deleteThreadMarkup(root_post_id string) {
|
||||
self.cache.DeleteThreadMarkup(root_post_id)
|
||||
}
|
||||
@ -414,19 +411,9 @@ func (self *httpFrontend) HandleNewPost(nntp frontendPost) {
|
||||
}
|
||||
entry := ArticleEntry{msgid, group}
|
||||
// regnerate thread
|
||||
self.regenThreadChan <- entry
|
||||
// regen the newsgroup we're in
|
||||
// TODO: regen only what we need to
|
||||
pages := self.daemon.database.GetGroupPageCount(group)
|
||||
// regen all pages
|
||||
var page int64
|
||||
for ; page < pages; page++ {
|
||||
req := groupRegenRequest{
|
||||
group: group,
|
||||
page: int(page),
|
||||
}
|
||||
self.regenGroupChan <- req
|
||||
}
|
||||
self.Regen(entry)
|
||||
// regenerate all board pages
|
||||
self.RegenerateBoard(group)
|
||||
}
|
||||
|
||||
// create a new captcha, return as json object
|
||||
@ -1565,9 +1552,6 @@ func NewHTTPFrontend(daemon *NNTPDaemon, cache CacheInterface, config map[string
|
||||
MaxAge: 600,
|
||||
}
|
||||
|
||||
front.regenThreadChan = front.cache.GetThreadChan()
|
||||
front.regenGroupChan = front.cache.GetGroupChan()
|
||||
|
||||
// liveui related members
|
||||
front.liveui_chnl = make(chan PostModel, 128)
|
||||
front.liveui_register = make(chan *liveChan)
|
||||
|
@ -35,7 +35,7 @@ type httpModUI struct {
|
||||
}
|
||||
|
||||
func createHttpModUI(frontend *httpFrontend) httpModUI {
|
||||
return httpModUI{frontend.regenAll, frontend.Regen, frontend.regenerateBoard, frontend.deleteThreadMarkup, frontend.deleteBoardMarkup, make(chan NNTPMessage), frontend.daemon, frontend.daemon.store, frontend.store, frontend.prefix, frontend.prefix + "mod/"}
|
||||
return httpModUI{frontend.regenAll, frontend.Regen, frontend.RegenerateBoard, frontend.deleteThreadMarkup, frontend.deleteBoardMarkup, make(chan NNTPMessage), frontend.daemon, frontend.daemon.store, frontend.store, frontend.prefix, frontend.prefix + "mod/"}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
)
|
||||
|
||||
type NullCache struct {
|
||||
regenThreadChan chan ArticleEntry
|
||||
regenGroupChan chan groupRegenRequest
|
||||
handler *nullHandler
|
||||
}
|
||||
|
||||
@ -202,20 +200,6 @@ func (self *NullCache) SetRequireCaptcha(required bool) {
|
||||
self.handler.requireCaptcha = required
|
||||
}
|
||||
|
||||
func (self *NullCache) pollRegen() {
|
||||
for {
|
||||
select {
|
||||
// consume regen requests
|
||||
case _ = <-self.regenGroupChan:
|
||||
{
|
||||
}
|
||||
case _ = <-self.regenThreadChan:
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// regen every page of the board
|
||||
func (self *NullCache) RegenerateBoard(group string) {
|
||||
}
|
||||
@ -225,20 +209,11 @@ func (self *NullCache) RegenOnModEvent(newsgroup, msgid, root string, page int)
|
||||
}
|
||||
|
||||
func (self *NullCache) Start() {
|
||||
go self.pollRegen()
|
||||
}
|
||||
|
||||
func (self *NullCache) Regen(msg ArticleEntry) {
|
||||
}
|
||||
|
||||
func (self *NullCache) GetThreadChan() chan ArticleEntry {
|
||||
return self.regenThreadChan
|
||||
}
|
||||
|
||||
func (self *NullCache) GetGroupChan() chan groupRegenRequest {
|
||||
return self.regenGroupChan
|
||||
}
|
||||
|
||||
func (self *NullCache) GetHandler() http.Handler {
|
||||
return self.handler
|
||||
}
|
||||
@ -249,8 +224,6 @@ func (self *NullCache) Close() {
|
||||
|
||||
func NewNullCache(prefix, webroot, name string, attachments bool, db Database, store ArticleStore) CacheInterface {
|
||||
cache := new(NullCache)
|
||||
cache.regenThreadChan = make(chan ArticleEntry, 16)
|
||||
cache.regenGroupChan = make(chan groupRegenRequest, 8)
|
||||
cache.handler = &nullHandler{
|
||||
prefix: prefix,
|
||||
name: name,
|
||||
|
@ -13,8 +13,7 @@ type VarnishCache struct {
|
||||
prefix string
|
||||
handler *nullHandler
|
||||
client *http.Client
|
||||
regenThreadChan chan ArticleEntry
|
||||
regenGroupChan chan groupRegenRequest
|
||||
threadsRegenChan chan ArticleEntry
|
||||
}
|
||||
|
||||
func (self *VarnishCache) invalidate(r string) {
|
||||
@ -33,8 +32,8 @@ func (self *VarnishCache) invalidate(r string) {
|
||||
func (self *VarnishCache) DeleteBoardMarkup(group string) {
|
||||
n, _ := self.handler.database.GetPagesPerBoard(group)
|
||||
for n > 0 {
|
||||
go self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, group, n))
|
||||
go self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, group, n))
|
||||
self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, group, n))
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, group, n))
|
||||
n--
|
||||
}
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/", self.varnish_url, self.prefix, group))
|
||||
@ -51,7 +50,7 @@ func (self *VarnishCache) RegenAll() {
|
||||
// we will do this as it's used by rengen on start for frontend
|
||||
groups := self.handler.database.GetAllNewsgroups()
|
||||
for _, group := range groups {
|
||||
self.handler.database.GetGroupThreads(group, self.regenThreadChan)
|
||||
self.handler.database.GetGroupThreads(group, self.threadsRegenChan)
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,34 +58,18 @@ func (self *VarnishCache) RegenFrontPage() {
|
||||
self.invalidate(fmt.Sprintf("%s%s", self.varnish_url, self.prefix))
|
||||
// TODO: this is also lazy af
|
||||
self.invalidate(fmt.Sprintf("%s%shistory.html", self.varnish_url, self.prefix))
|
||||
self.invalidateUkko(10)
|
||||
}
|
||||
|
||||
func (self *VarnishCache) invalidateUkko() {
|
||||
func (self *VarnishCache) invalidateUkko(pages int) {
|
||||
// TODO: invalidate paginated ukko
|
||||
self.invalidate(fmt.Sprintf("%s%sukko.html", self.varnish_url, self.prefix))
|
||||
self.invalidate(fmt.Sprintf("%s%soverboard/", self.varnish_url, self.prefix))
|
||||
self.invalidate(fmt.Sprintf("%s%so/", self.varnish_url, self.prefix))
|
||||
// TODO: this is lazy af
|
||||
self.RegenFrontPage()
|
||||
}
|
||||
|
||||
func (self *VarnishCache) pollRegen() {
|
||||
for {
|
||||
select {
|
||||
// consume regen requests
|
||||
case ev := <-self.regenGroupChan:
|
||||
{
|
||||
self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, ev.group, ev.page))
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, ev.group, ev.page))
|
||||
if ev.page == 0 {
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/", self.varnish_url, self.prefix, ev.group))
|
||||
}
|
||||
}
|
||||
case ev := <-self.regenThreadChan:
|
||||
{
|
||||
self.Regen(ev)
|
||||
}
|
||||
}
|
||||
n := 0
|
||||
for n < pages {
|
||||
self.invalidate(fmt.Sprintf("%s%so/%d/", self.varnish_url, self.prefix, n))
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,8 +77,8 @@ func (self *VarnishCache) pollRegen() {
|
||||
func (self *VarnishCache) RegenerateBoard(group string) {
|
||||
n, _ := self.handler.database.GetPagesPerBoard(group)
|
||||
for n > 0 {
|
||||
go self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, group, n))
|
||||
go self.invalidate(fmt.Sprintf("%s%s%s/%d/", self.varnish_url, self.prefix, group, n))
|
||||
self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, group, n))
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, group, n))
|
||||
n--
|
||||
}
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/", self.varnish_url, self.prefix, group))
|
||||
@ -103,28 +86,29 @@ func (self *VarnishCache) RegenerateBoard(group string) {
|
||||
|
||||
// regenerate pages after a mod event
|
||||
func (self *VarnishCache) RegenOnModEvent(newsgroup, msgid, root string, page int) {
|
||||
self.regenGroupChan <- groupRegenRequest{newsgroup, page}
|
||||
self.regenThreadChan <- ArticleEntry{newsgroup, root}
|
||||
self.Regen(ArticleEntry{newsgroup, root})
|
||||
if page == 0 {
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/", self.varnish_url, self.prefix, newsgroup))
|
||||
}
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, newsgroup, page))
|
||||
}
|
||||
|
||||
func (self *VarnishCache) poll() {
|
||||
for {
|
||||
ent := <-self.threadsRegenChan
|
||||
self.Regen(ent)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *VarnishCache) Start() {
|
||||
go self.pollRegen()
|
||||
go self.poll()
|
||||
}
|
||||
|
||||
func (self *VarnishCache) Regen(msg ArticleEntry) {
|
||||
go self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, msg.Newsgroup(), 0))
|
||||
go self.invalidate(fmt.Sprintf("%s%s%s/%d/", self.varnish_url, self.prefix, msg.Newsgroup(), 0))
|
||||
go self.invalidate(fmt.Sprintf("%s%sthread-%s.html", self.varnish_url, self.prefix, HashMessageID(msg.MessageID())))
|
||||
go self.invalidate(fmt.Sprintf("%s%st/%s/", self.varnish_url, self.prefix, HashMessageID(msg.MessageID())))
|
||||
self.invalidateUkko()
|
||||
}
|
||||
|
||||
func (self *VarnishCache) GetThreadChan() chan ArticleEntry {
|
||||
return self.regenThreadChan
|
||||
}
|
||||
|
||||
func (self *VarnishCache) GetGroupChan() chan groupRegenRequest {
|
||||
return self.regenGroupChan
|
||||
self.invalidate(fmt.Sprintf("%s%s%s-%d.html", self.varnish_url, self.prefix, msg.Newsgroup(), 0))
|
||||
self.invalidate(fmt.Sprintf("%s%sb/%s/%d/", self.varnish_url, self.prefix, msg.Newsgroup(), 0))
|
||||
self.invalidate(fmt.Sprintf("%s%sthread-%s.html", self.varnish_url, self.prefix, HashMessageID(msg.MessageID())))
|
||||
self.invalidate(fmt.Sprintf("%s%st/%s/", self.varnish_url, self.prefix, HashMessageID(msg.MessageID())))
|
||||
}
|
||||
|
||||
func (self *VarnishCache) GetHandler() http.Handler {
|
||||
@ -141,8 +125,7 @@ func (self *VarnishCache) SetRequireCaptcha(required bool) {
|
||||
|
||||
func NewVarnishCache(varnish_url, bind_addr, prefix, webroot, name string, attachments bool, db Database, store ArticleStore) CacheInterface {
|
||||
cache := new(VarnishCache)
|
||||
cache.regenThreadChan = make(chan ArticleEntry, 16)
|
||||
cache.regenGroupChan = make(chan groupRegenRequest, 8)
|
||||
cache.threadsRegenChan = make(chan ArticleEntry)
|
||||
local_addr, err := net.ResolveTCPAddr("tcp", bind_addr)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to resolve %s for varnish cache: %s", bind_addr, err)
|
||||
|
Reference in New Issue
Block a user