How to reduce impact of deployments on a liveview?

LiveView 1.0.2 still has the change I was referring to.

One thing you could try is to open up a page and then put this into the browser console:

['unload', 'beforeunload'].forEach(function (eventName) {
  window.addEventListener(eventName, function () {
    debugger;
  });
});

This will cause the JS execution to pause as soon as the page tries to reload, letting you inspect the console logs and also WebSocket messages. If you then trigger a deploy that causes a reload, you might find out more.

4 Likes

ok, I’ve managed to reproduce again, with the debugger.

Update on reproducing - I updated a random file and deployed, and there was no issue. I updated the router with a fake route, and the issue happened. I haven’t confirmed yet that this always reproduces the issue, but could be important.

When the debugger fired, i saw an error in the console about the socket failing to connect. I presume this is the websocket trying to reconnect.

socket.js:348
WebSocket connection to 'wss://(redacted)/live/websocket?_csrf_token=(redacted)&vsn=2.0.0' failed:
transportConnect@socket.js:348

The debugger helped here I think… (using the breakpoint triggered by the unload)

Here’s the stack trace:

It looks like the redirect is caused by an error on connection. If I look at the conn.onmessage I see

where the payload for event is

event: {
  ...
  data:  ["25","25","lv:phx-(redacted)","phx_reply",{"status":"error","response":{"reason":"unauthorized"}}]
  ...
}

So some kind of authorization issue, but I don’t think that’s coming from my application?

1 Like

Sorry for the late reply! The “unauthorized” is sent by LV and corresponds to the log message you’ve also seen a couple posts back. It would be interesting to see what message was sent on the websocket for the join event. You should only see that log when the join message sends a “redirect” URL on join (which initiates a live redirect). For a regular join, you should instead see a “url” parameter:

So the question would be why the client tries to do a live navigation after you deploy when it should just reconnect. That the live navigation itself fails is expected after a router change.

hrm, ok, i’ve got some of those logs around the connection, does this help at all?


When the issue triggers, I get a new websocket connection in the browser console. This shows what you described - a redirect, which is followed by that same authorization error, and then the leave events.

# message 1 (06:30:50)

[
  "19",
  "19",
  "lv:phx-GC2DPcp2YEoImw2C",
  "phx_join",
  {
    "redirect": "https://(redacted)",
    "params": {
      "_csrf_token": "(redacted)",
      "_track_static": [
        "https://(redacted)/assets/app.css",
        "https://(redacted)/assets/app.js"
      ],
      "_mounts": 1,
      "_mount_attempts": 0,
      "_live_referer": "(redacted)"
    },
    "session": "(redacted)",
    "static": "(redacted)",
    "flash": null
  }
]

# message 1 response (06:30:51)

[
  "19",
  "19",
  "lv:phx-GC2DPcp2YEoImw2C",
  "phx_reply",
  {
    "status": "error",
    "response": {
      "reason": "unauthorized"
    }
  }
]

# message 2  (06:30:51)

[
  "19",
  "20",
  "lv:phx-GC2DPcp2YEoImw2C",
  "phx_leave",
  {}
]

After this happens, I then see the log in the server logs (assuming the timestamps are reasonably accurate).

2025-03-17 06:30:51.022 [warning]
mfa=Phoenix.LiveView.Channel.authorize_session/3
navigate event to "(redacted)" failed because you are redirecting across live_sessions. A full page reload will be performed instead

Then in the browser, I get the next websocket connecting. This seems more like the full page load, not errors in this one.

# message 1 (06:30:56)
[
  "4",
  "4",
  "lv:phx-GC2DWaHB-O9pYgJC",
  "phx_join",
  {
    "url": "(redacted)",
    "params": {
      "_csrf_token": "(redacted)",
      "_track_static": [
        "https://(redacted)/assets/app.css",
        "https://(redacted)/assets/app.js"
      ],
      "_mounts": 0,
      "_mount_attempts": 0
    },
    "session": "(redacted)",
    "static": "(redacted)"
  }
]

# message 1 response

[
  "4",
  "4",
  "lv:phx-GC2DWaHB-O9pYgJC",
  "phx_reply",
  {
    "status": "ok",
    "response": {
      "liveview_version": "1.0.2",
      "rendered": {
        (bunch of html/diff)
      }
    }
  }
]

I think i’ve found something potentially specific to the issue.

To reproduce, so I have been changing the router. But this didn’t always reproduce. Then when I was doing the recent reproducing for logs, I found something interesting. When looking at the redirect event, i saw _live_referer, and noticed that the redirect url was different to the first socket url. i.e. I had done a live-navigation after the first page load, then triggered the issue with a deploy. I replicated this, and the issue triggered, so it may be relevant.

e.g. (stripping out everything except interesting bits)

initial page load

  "phx_join",
  {
    "url": "view-a",
  }

then i browse to “view-b”, change the router.ex, and deploy

then the socket gets the redirect message

  "phx_join",
  {
    "redirect": "view-b",
    "params": {
      "_live_referer": "view-a"
    }
  }

This helped, I was able to reproduce. I’ll investigate!

4 Likes

We got a PR lined up to fix this - should hopefully land in the next release soon!

You can try

{:phoenix_live_view, github: "phoenixframework/phoenix_live_view, branch: "sd-live-session-vsn", override: true}

to test it!

6 Likes

thanks for your help @steffend, much appreciated!

1 Like