phoenix
phoenix copied to clipboard
Channel.push may cause Push's ref be generated twice
Environment
- Elixir version (elixir -v): 1.12.3
- Phoenix version (mix deps): 1.6.11
- Operating system: Windows 11
Expected behavior
A push's ref should not change unless the push was resend.
Actual behavior
When invoke channel.push and when channel.canPush() returns false, the push will be put in channel's pushBuffer,
if(this.canPush()){
pushEvent.send()
} else {
pushEvent.startTimeout()
this.pushBuffer.push(pushEvent)
}
Later when the channel joined, pushes in pushBuffer will invoke the send method which invoke the startTimeout method.
The problem is startTimeout will be called twice on a push if the channel can not push immediately, cause the ref in buffered push be re-generated. And of course the corresponding refEvent timeoutTimer become useless.
startTimeout(){
if(this.timeoutTimer){ this.cancelTimeout() }
this.ref = this.channel.socket.makeRef()
this.refEvent = this.channel.replyEventName(this.ref)
this.channel.on(this.refEvent, payload => {
this.cancelRefEvent()
this.cancelTimeout()
this.receivedResp = payload
this.matchReceive(payload)
})
this.timeoutTimer = setTimeout(() => {
this.trigger("timeout", {})
}, this.timeout)
}
Maybe we should use the resend method instead of send on buffered push.