Skip to content

Commit

Permalink
Fix: session result handler not called on timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
ivard committed Oct 19, 2023
1 parent 8a6ae19 commit 86334a1
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 50 deletions.
59 changes: 9 additions & 50 deletions server/irmaserver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,14 @@ func (s *Server) startNextSession(

if handler != nil {
go func() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
updateChan, err := s.sessions.subscribeUpdates(ctx, ses.RequestorToken)
statusChan, err := s.sessionStatusChannel(context.Background(), ses.RequestorToken, ses.timeout(s.conf))
if err != nil {
s.conf.Logger.WithError(err).Error("Failed to subscribe to session status changes for handler")
s.conf.Logger.WithError(err).Error("Failed to subscribe to session status updates for handler")
return
}
for update := range updateChan {
if update.Status.Finished() {
if err := s.sessions.transaction(ctx, ses.RequestorToken, func(ses *sessionData) (bool, error) {
for status := range statusChan {
if status.Finished() {
if err := s.sessions.transaction(context.Background(), ses.RequestorToken, func(ses *sessionData) (bool, error) {
handler(ses.Result)
return false, nil
}); err != nil {
Expand Down Expand Up @@ -473,52 +471,13 @@ func (s *Server) SessionStatus(requestorToken irma.RequestorToken) (statusChan c
return nil, errors.New("SessionStatus cannot be used in combination with Redis.")
}

ctx, cancel := context.WithCancel(context.Background())
updateChan, err := s.sessions.subscribeUpdates(ctx, requestorToken)
if err != nil {
cancel()
return nil, err
}
var timeoutTime time.Time
if err := s.sessions.transaction(ctx, requestorToken, func(session *sessionData) (bool, error) {
timeoutTime = time.Now().Add(session.timeout(s.conf))
var timeout time.Duration
if err := s.sessions.transaction(context.Background(), requestorToken, func(session *sessionData) (bool, error) {
timeout = session.timeout(s.conf)
return false, nil
}); err != nil {
cancel()
return nil, err
}

statusChan = make(chan irma.ServerStatus, 4)
go func() {
defer cancel()

var currStatus irma.ServerStatus
for {
select {
case update, ok := <-updateChan:
if !ok {
close(statusChan)
return
}
if currStatus == update.Status {
continue
}
currStatus = update.Status

statusChan <- currStatus

if currStatus.Finished() {
close(statusChan)
return
}
timeoutTime = time.Now().Add(update.timeout(s.conf))
case <-time.After(time.Until(timeoutTime)):
statusChan <- irma.ServerStatusTimeout
close(statusChan)
return
}
}
}()

return statusChan, nil
return s.sessionStatusChannel(context.Background(), requestorToken, timeout)
}
45 changes: 45 additions & 0 deletions server/irmaserver/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,51 @@ func (s *Server) serverSentEventsHandler(initialSession *sessionData, updateChan
}
}

func (s *Server) sessionStatusChannel(ctx context.Context, token irma.RequestorToken, initialTimeout time.Duration) (
chan irma.ServerStatus, error) {
ctx, cancel := context.WithCancel(ctx)
updateChan, err := s.sessions.subscribeUpdates(ctx, token)
if err != nil {
cancel()
return nil, err
}

statusChan := make(chan irma.ServerStatus, 4)
timeoutTime := time.Now().Add(initialTimeout)
go func() {
defer cancel()

var currStatus irma.ServerStatus
for {
select {
case update, ok := <-updateChan:
if !ok {
close(statusChan)
return
}
if currStatus == update.Status {
continue
}
currStatus = update.Status

statusChan <- currStatus

if currStatus.Finished() {
close(statusChan)
return
}
timeoutTime = time.Now().Add(update.timeout(s.conf))
case <-time.After(time.Until(timeoutTime)):
statusChan <- irma.ServerStatusTimeout
close(statusChan)
return
}
}
}()

return statusChan, nil
}

func (s *Server) newSession(
ctx context.Context,
action irma.Action,
Expand Down

0 comments on commit 86334a1

Please sign in to comment.