Prevent duplicate workflow prompts from sending

This commit is contained in:
Tomaž Jerman
2022-04-19 14:33:25 +02:00
parent 6fd2288dfd
commit 9c00264626
3 changed files with 45 additions and 4 deletions
+11 -1
View File
@@ -445,7 +445,17 @@ func (svc *session) stateChangeHandler(ctx context.Context) wfexec.StateChangeHa
// Send the pending prompts to user
if svc.promptSender != nil {
for _, pp := range s.AllPendingPrompts() {
for _, pp := range s.UnsentPendingPrompts() {
// Prevent prompts from being re-sent
//
// This here collects all of the pending prompts and (re-)sends them.
// The problem occurs if you display multiple prompts in parallel --
// they get duplicated.
//
// Patching back-end with this simple fix, but we should probably
// refactor the logic that handles prompting a bit.
pp.Original.MarkSent()
if err := svc.promptSender.Send("workflowSessionPrompt", pp, pp.OwnerId); err != nil {
svc.log.Error("failed to send prompt to user", zap.Error(err))
}
+11 -1
View File
@@ -1,8 +1,9 @@
package wfexec
import (
"github.com/cortezaproject/corteza-server/pkg/expr"
"time"
"github.com/cortezaproject/corteza-server/pkg/expr"
)
type (
@@ -16,6 +17,8 @@ type (
// state to be resumed
state *State
sent bool
// prompt reference; something client can use
// for orientation, what kind of prompt is expected
ref string
@@ -28,6 +31,8 @@ type (
StateID uint64 `json:"stateID,string"`
Payload *expr.Vars `json:"payload"`
OwnerId uint64 `json:"-"`
Original *prompted `json:"-"`
}
ResumedPrompt struct {
@@ -47,6 +52,7 @@ func (p *prompted) toPending() *PendingPrompt {
StateID: p.state.stateId,
Payload: p.payload,
OwnerId: p.ownerId,
Original: p,
}
}
@@ -56,3 +62,7 @@ func (p *prompted) toResumed() *ResumedPrompt {
OwnerId: p.ownerId,
}
}
func (p *prompted) MarkSent() {
p.sent = true
}
+23 -2
View File
@@ -293,9 +293,30 @@ func (s *Session) AllPendingPrompts() (out []*PendingPrompt) {
defer s.mux.RUnlock()
s.mux.RLock()
out = make([]*PendingPrompt, 0, len(s.prompted))
return s.pendingPrompts(s.prompted)
}
for _, p := range s.prompted {
// UnsentPendingPrompts returns unsent pending prompts for all user
func (s *Session) UnsentPendingPrompts() (out []*PendingPrompt) {
defer s.mux.RUnlock()
s.mux.RLock()
aux := s.pendingPrompts(s.prompted)
for _, p := range aux {
if p.Original.sent {
continue
}
out = append(out, p)
}
return
}
func (s *Session) pendingPrompts(prompted map[uint64]*prompted) (out []*PendingPrompt) {
out = make([]*PendingPrompt, 0, len(prompted))
for _, p := range prompted {
pending := p.toPending()
pending.SessionID = s.id
out = append(out, pending)