Skip to content

client, test/suites: forward session timeout cause over websocket - #1519

Open
shardool-patil wants to merge 2 commits into
canonical:mainfrom
shardool-patil:fix/session-timeout-forwarding
Open

client, test/suites: forward session timeout cause over websocket#1519
shardool-patil wants to merge 2 commits into
canonical:mainfrom
shardool-patil:fix/session-timeout-forwarding

Conversation

@shardool-patil

Copy link
Copy Markdown

Description

When a trust establishment session expires, the client previously received a generic connection error (websocket: close 1006: unexpected EOF) instead of the actual cause (Session timeout exceeded)[cite: 5].

Changes

  • client/websocket.go:
    • Updated WriteClose to write ControlClose directly over the WebSocket under writeLock so close frames are sent even when gwCtx is canceled on timeout[cite: 5].
    • Updated ReceiveWithContext to check channel closure and return context.Cause(w.ctx)[cite: 5].
  • test/suites/basic.sh:
    • Added a test case in test_interactive with SESSION_TIMEOUT="5" verifying that both the initiator and joiner receive "Session timeout exceeded"[cite: 2].

Checklist

Related issues

@roosterfish i have taken into consideration the insights you provided and resolved the issue, so take a look at it when you get time.

@roosterfish roosterfish left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look at this, please see my comments on the test.

Comment thread test/suites/basic.sh Outdated
echo "Initiate a MicroCloud cluster with a short session timeout and verify the joiner receives the timeout error"
export MULTI_NODE="yes"
export LOOKUP_IFACE="enp5s0"
export EXPECT_PEERS=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess what you would need here is export EXPECT_PEERS=2, then let only micro02 attempt to join. As micro01 is the initiator, it will wait for two peers, but only micro02 reaches out so it will cause the session to expire.

Comment thread test/suites/basic.sh Outdated
validate_system_microovn ${m}
done
}
} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline missing.

Comment thread test/suites/basic.sh Outdated
lxc exec micro04 -- tail -1 out | grep "Failed waiting during join: Initiator aborted the setup" -q

# Initiate a MicroCloud cluster with a short session timeout and verify the joiner receives "Session timeout exceeded".
reset_systems 2 3 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 is the number of peers, 3 number of disks, 0 number of extra interfaces.

As we never reach the config stage and don't require a disk, you can also do 2 0 0 here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves MicroCloud’s WebSocket session handling so that when a trust establishment session expires, the client receives the real cancellation cause (e.g., “Session timeout exceeded”) rather than a generic abnormal WebSocket EOF error, aligning behavior with issue #1245.

Changes:

  • Adjusts the WebSocket gateway close-path to reliably send a ControlClose message even when the gateway context is canceled.
  • Improves receive behavior to surface the gateway context cause when the receive channel closes.
  • Adds a system test intended to validate that both initiator and joiner surface the timeout error.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
client/websocket.go Ensures close-cause forwarding works reliably and improves receive-side error reporting when the socket closes.
test/suites/basic.sh Adds an interactive test case intended to validate session-timeout error propagation to initiator/joiner.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread test/suites/basic.sh Outdated
Comment on lines +456 to +458
export SESSION_TIMEOUT="5"

! join_session init micro01 micro02 || false
Comment thread test/suites/basic.sh Outdated
Comment on lines +443 to +447
# Initiate a MicroCloud cluster with a short session timeout and verify the joiner receives "Session timeout exceeded".
reset_systems 2 3 0
unset_interactive_vars

echo "Initiate a MicroCloud cluster with a short session timeout and verify the joiner receives the timeout error"
Comment thread client/websocket.go Outdated
return context.Cause(w.ctx)
}

return errors.New("Websocket connection closed")
@shardool-patil

Copy link
Copy Markdown
Author

@roosterfish i have addressed all the requested changes:

  • test/suites/basic.sh: Set EXPECT_PEERS=2, clarified the test comment and echo message to verify both initiator and joiner, and added the missing EOF newline[cite: 2, 3].
  • test/includes/microcloud.sh: Updated microcloud_interactive to pass ${SESSION_TIMEOUT:-60} dynamically and added SESSION_TIMEOUT to unset_interactive_vars[cite: 2].

take a look whenever possible

Signed-off-by: Shardool Patil <shardoolpatil999@gmail.com>
@shardool-patil
shardool-patil force-pushed the fix/session-timeout-forwarding branch from b287951 to 4ffe082 Compare August 21, 2026 11:28
@roosterfish

Copy link
Copy Markdown
Contributor

See the test failure https://github.com/canonical/microcloud/actions/runs/32477357735/job/96766897819?pr=1519#step:3:45500.
I suspect what is happening is that the session expires too early now. Maybe let's leave the 60s default (no need to make it configurable in this case).

@roosterfish
roosterfish marked this pull request as draft August 21, 2026 15:41
@shardool-patil
shardool-patil force-pushed the fix/session-timeout-forwarding branch from 4ffe082 to 14a4c0b Compare August 21, 2026 16:41
@shardool-patil

Copy link
Copy Markdown
Author

See the test failure https://github.com/canonical/microcloud/actions/runs/32477357735/job/96766897819?pr=1519#step:3:45500. I suspect what is happening is that the session expires too early now. Maybe let's leave the 60s default (no need to make it configurable in this case).

@roosterfish I have worked and handled the requested changes so take a look at the code.

@roosterfish
roosterfish marked this pull request as ready for review August 24, 2026 11:42
@shardool-patil
shardool-patil force-pushed the fix/session-timeout-forwarding branch from 14a4c0b to c3f95c6 Compare August 25, 2026 02:27
@shardool-patil

Copy link
Copy Markdown
Author

@roosterfish I switched the test to reset_systems 3 0 0 because with reset_systems 2 0 0, micro03 is paused by default. Since EXPECT_PEERS=2 triggers table:expect 2, micro01 hangs during mDNS peer discovery waiting for a nonexistent second peer before the session ever starts. Running reset_systems 3 0 0 allows micro01 to discover both peers, select them, connect with micro02, and wait for micro03 until the session timeout triggers. Does reset_systems 3 0 0 work for you here?

Signed-off-by: Shardool Patil <shardoolpatil999@gmail.com>
@shardool-patil
shardool-patil force-pushed the fix/session-timeout-forwarding branch from c3f95c6 to e98fe8e Compare August 25, 2026 16:16
@shardool-patil

Copy link
Copy Markdown
Author

@roosterfish I've updated test/suites/basic.sh:

  • Switched to reset_systems 3 0 0 and disabled storage setup (SETUP_ZFS="no", SETUP_CEPH="no").
  • Kept EXPECT_PEERS=2 with join_session init micro01 micro02 so micro01 connects with micro02 and waits for micro03 until the default 60s session timeout triggers.
    With reset_systems 2 0 0, micro03 is paused by default, causing micro01 to hang during mDNS peer discovery (table:expect 2) before the session can start. 3 0 0 keeps micro03 running so discovery succeeds without configuring any unused storage devices.

Please take a look at this setup before re-running the tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Session expiry isn't forwarded to the client

3 participants