Why does Phoenix channel push stop working after waking the computer from sleep?

I need help understanding why Phoenix channel push events would stop working after
putting the computer to sleep and then waking it up. I believe I fixed the problem
now, but it is not clear why the original solution was not working.

The phoenix app where I was having this issue is hosted locally. I would appreciate
if someone could explain what is happening here; what is wrong with problem code
and why the solution code works. The post is long, but the changes to code from
problem to solution are small. Essentially, it involves changing from (1) assignment to a
global variable to (2) assignment first to a local variable and then assigning the global
variable to that local variable.

This is how I had first set up my JS code:

problem code

// global JS variable
export let myChan; 


export const joinSocket = (token) => {
  let socket = new Socket("/socket");

  socket.connect();

  socket.onOpen(() => {
    console.log("Socket connection was opened...");
    myChan = socket.channel("room:" + roomid,
                                  {token: token, roomid: roomid});

    myChan.join()
          .receive("ok", (resp) => {
                    console.log("Joined myChan successfully...")
                    getSomeData();
                  })
          .receive("error", (resp) => {console.log("Unable to join myChan:", resp)})

    myChan.onError((err) => {
      console.log("myChan error: ", err)
    })
    myChan.onClose(() => {
      console.log("myChan close event fired...")
    })
    
    
export const getSomeData = function() {
    myChan.push("getdata", {token: get(tokenStore)})
                .receive("ok", (resp) => {
                    console.log("resp getdata: ", resp);
                })
}

The push event in getSomeData and other functions worked well when after first visiting the url (localhost url)
and after any refresh. As expected, the connection would take place and I would get the data from the server.
However, if I put the computer to sleep, and then woke it up, I would again see the statements
“Socket connection was opened…” followed by “Joined myChan successfully…” in the browser console. But, this
time getSomeData did not get any data. This is because the push was failing without any error message either
in the browser or in the iex repl. This is true also for any other push events that are triggered by user actions

  • they don’t work.

Solution that works

The following code that replaces assignment to the global variable myChan with a local variable
and then re-assigning myChan to that local variable works well. Now, when I sleep and wake up the
computer, I see logged messages and getSomeData() gets the expected data again. Other push events
also work. Why is the above not working, but the below is? Isn’t myChan reassigned in the above code,
because the onOpen event is fired.

solution code

// global JS variable
export let myChan; 


export const joinSocket = (token) => {
  let socket = new Socket("/socket");

  socket.connect();

  socket.onOpen(() => {
    console.log("Socket connection was opened...");
    let localChan = socket.channel("room:" + roomid,
                                  {token: token, roomid: roomid});

    localChan.join()
          .receive("ok", (resp) => {
                    console.log("Joined localChan successfully...")
                    myChan = localChan;
                    getSomeData();
                  })
          .receive("error", (resp) => {console.log("Unable to join localChan:", resp)})

    localChan.onError((err) => {
      console.log("localChan error: ", err)
    })
    localChan.onClose(() => {
      console.log("localChan close event fired...")
    })
    
    
export const getSomeData = function() {
    myChan.push("getdata", {token: get(tokenStore)})
                .receive("ok", (resp) => {
                    console.log("resp getdata: ", resp);
                })
}
2 Likes

Because JavaScript. :sweat_smile:

But seriously, I am curious as well.

2 Likes

I think there is something related to JS GC or object lifecycle on client side

This jumped out at me, may be a red herring though

Thank you @evadne. Unfortunately, I don’t understand why this piece of code is causing the issue that I am experiencing.