fix(runtime): sync on sse reconnect
This commit is contained in:
@@ -244,7 +244,6 @@ func (c *Context) sendPatch(p patch) {
|
|||||||
select {
|
select {
|
||||||
case patchChan <- p:
|
case patchChan <- p:
|
||||||
default: // closed or buffer full - drop patch without blocking
|
default: // closed or buffer full - drop patch without blocking
|
||||||
c.app.logWarn(c, "view out of sync: sse stream closed or queue is full")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,11 +319,8 @@ func (c *Context) ExecScript(s string) {
|
|||||||
func (c *Context) stopAllRoutines() {
|
func (c *Context) stopAllRoutines() {
|
||||||
select {
|
select {
|
||||||
case c.ctxDisposedChan <- struct{}{}:
|
case c.ctxDisposedChan <- struct{}{}:
|
||||||
c.app.logDebug(c, "stopped all routines")
|
|
||||||
default:
|
default:
|
||||||
c.app.logDebug(c, "did not stop all routines")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newContext(id string, route string, v *V) *Context {
|
func newContext(id string, route string, v *V) *Context {
|
||||||
@@ -339,6 +335,7 @@ func newContext(id string, route string, v *V) *Context {
|
|||||||
componentRegistry: make(map[string]*Context),
|
componentRegistry: make(map[string]*Context),
|
||||||
actionRegistry: make(map[string]func()),
|
actionRegistry: make(map[string]func()),
|
||||||
signals: new(sync.Map),
|
signals: new(sync.Map),
|
||||||
|
patchChan: make(chan patch, 100),
|
||||||
ctxDisposedChan: make(chan struct{}, 1),
|
ctxDisposedChan: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
via.go
37
via.go
@@ -154,7 +154,9 @@ func (v *V) Page(route string, initContextFn func(c *Context)) {
|
|||||||
}
|
}
|
||||||
v.mux.HandleFunc("GET "+route, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
v.mux.HandleFunc("GET "+route, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
v.logDebug(nil, "GET %s", r.URL.String())
|
v.logDebug(nil, "GET %s", r.URL.String())
|
||||||
if strings.Contains(r.URL.Path, "favicon") {
|
if strings.Contains(r.URL.Path, "favicon") ||
|
||||||
|
strings.Contains(r.URL.Path, ".well-known") ||
|
||||||
|
strings.Contains(r.URL.Path, "js.map") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := fmt.Sprintf("%s_/%s", route, genRandID())
|
id := fmt.Sprintf("%s_/%s", route, genRandID())
|
||||||
@@ -235,9 +237,6 @@ func (v *V) HandleFunc(pattern string, f http.HandlerFunc) {
|
|||||||
|
|
||||||
// Start starts the Via HTTP server on the given address.
|
// Start starts the Via HTTP server on the given address.
|
||||||
func (v *V) Start() {
|
func (v *V) Start() {
|
||||||
if v.cfg.DevMode {
|
|
||||||
v.devModeRestore()
|
|
||||||
}
|
|
||||||
v.logInfo(nil, "via started at [%s]", v.cfg.ServerAddress)
|
v.logInfo(nil, "via started at [%s]", v.cfg.ServerAddress)
|
||||||
log.Fatalf("[fatal] %v", http.ListenAndServe(v.cfg.ServerAddress, v.mux))
|
log.Fatalf("[fatal] %v", http.ListenAndServe(v.cfg.ServerAddress, v.mux))
|
||||||
}
|
}
|
||||||
@@ -307,7 +306,7 @@ func (v *V) devModeRemovePersisted(c *Context) {
|
|||||||
v.logDebug(c, "devmode removed persisted ctx from file")
|
v.logDebug(c, "devmode removed persisted ctx from file")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *V) devModeRestore() {
|
func (v *V) devModeRestore(cID string) {
|
||||||
p := filepath.Join(".via", "devmode", "ctx.json")
|
p := filepath.Join(".via", "devmode", "ctx.json")
|
||||||
file, err := os.Open(p)
|
file, err := os.Open(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -324,17 +323,18 @@ func (v *V) devModeRestore() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for ctxID, pageRoute := range ctxRegMap {
|
for ctxID, pageRoute := range ctxRegMap {
|
||||||
pageInitFn, ok := v.devModePageInitFnMap[pageRoute]
|
if ctxID == cID {
|
||||||
if !ok {
|
pageInitFn, ok := v.devModePageInitFnMap[pageRoute]
|
||||||
v.logWarn(nil, "devmode could not restore ctx from file: page init fn for route '%s' not found", pageRoute)
|
if !ok {
|
||||||
continue
|
v.logWarn(nil, "devmode could not restore ctx from file: page init fn for route '%s' not found", pageRoute)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c := newContext(ctxID, pageRoute, v)
|
||||||
|
pageInitFn(c)
|
||||||
|
v.registerCtx(c)
|
||||||
|
v.logDebug(c, "devmode restored ctx")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := newContext(ctxID, pageRoute, v)
|
|
||||||
pageInitFn(c)
|
|
||||||
v.registerCtx(c)
|
|
||||||
}
|
}
|
||||||
v.logDebug(nil, "devmode restored ctx registry")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type patchType int
|
type patchType int
|
||||||
@@ -375,6 +375,12 @@ func New() *V {
|
|||||||
var sigs map[string]any
|
var sigs map[string]any
|
||||||
_ = datastar.ReadSignals(r, &sigs)
|
_ = datastar.ReadSignals(r, &sigs)
|
||||||
cID, _ := sigs["via-ctx"].(string)
|
cID, _ := sigs["via-ctx"].(string)
|
||||||
|
|
||||||
|
if v.cfg.DevMode {
|
||||||
|
if _, err := v.getCtx(cID); err != nil {
|
||||||
|
v.devModeRestore(cID)
|
||||||
|
}
|
||||||
|
}
|
||||||
c, err := v.getCtx(cID)
|
c, err := v.getCtx(cID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.logErr(nil, "sse stream failed to start: %v", err)
|
v.logErr(nil, "sse stream failed to start: %v", err)
|
||||||
@@ -385,9 +391,6 @@ func New() *V {
|
|||||||
|
|
||||||
v.logDebug(c, "SSE connection established")
|
v.logDebug(c, "SSE connection established")
|
||||||
|
|
||||||
c.patchChan = make(chan patch, 1000)
|
|
||||||
defer close(c.patchChan)
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
c.Sync()
|
c.Sync()
|
||||||
}()
|
}()
|
||||||
|
|||||||
Reference in New Issue
Block a user