Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disconnected agent causes invalid_state_err #14

Open
bensheldon opened this issue Sep 27, 2011 · 1 comment
Open

Disconnected agent causes invalid_state_err #14

bensheldon opened this issue Sep 27, 2011 · 1 comment

Comments

@bensheldon
Copy link

(sorry to open this ticket, but I'm not sure if this is a problem on my setup or with push-it...)

Node throws an invalid_state_err when trying to send a message after refreshing the browser window. I think something isn't properly clearing the list of connected agents (i.e. trying to send to a disconnected agent), but I'm not entirely sure.

This is nodejs's console.log:

connected agent: SeKhwfqBtwYspYaveEn5B8
Agent.id(SeKhwfqBtwYspYaveEn5B8) sent message.uuid(_8iRNza40f0ANcyQ_T-yyS)
**REFRESH BROWSER**
connected agent: LaJPvL75EkCD3xJZVeEd_K
Agent.id(LaJPvL75EkCD3xJZVeEd_K) sent message.uuid(S9U-dlf8jun9DmtxqVUlPu)
disconnected agent: SeKhwfqBtwYspYaveEn5B8
Agent.id(LaJPvL75EkCD3xJZVeEd_K) sent message.uuid(LeA-VK048e0xY_XzpIO_2h)

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: INVALID_STATE_ERR
    at Error (unknown source)
    at Session.send (/Users/SlicedBread/node_modules/push-it/node_modules/sockjs/lib/transport.js:124:15)
    at Agent.send (/Users/SlicedBread/node_modules/push-it/server/models/agent.js:33:17)
    at Object.received (/Users/SlicedBread/node_modules/push-it/server/mqs/subscription_manager.js:34:26)
    at Object.callback (/Users/SlicedBread/node_modules/push-it/server/mqs/subscription_manager.js:25:12)
    at Array.<anonymous> (/Users/SlicedBread/node_modules/push-it/server/mqs/in_memory.js:47:18)
    at EventEmitter._tickCallback (node.js:126:26)

Thanks for the help and please let me know if I can better further describe the issue or help replicate it.

@bensheldon
Copy link
Author

Tracking this down, it looks like the issue is that when agents disconnect, they are only removed from the list of agents (Agent.remove()), not unsubscribed from the channels. Thus when a new message is pushed out to a channel, it tries to send it to agents who have already disconnected. I tried wrapping SubscriptionManager.received in an error handler, at it "solved" the problem:

proto.received = function(chan, message){
  var ss = this.subscriptions[chan];
  if(ss){
    for(var agentId in ss.agents){
      try {
        // attempt to send the message
        ss.agents[agentId].send(message);
      }catch(err){
        if (err = 'invalid_state_err') {
          // agent doesn't exist, so unsubscribe
          ss.removeAgent(ss.agents[agentId]);
        }
      }
    }
  }
};

It's still a bit of spaghetti code since optimally the SubscriptionSet should be flushed in __onDisconnect. One issue is that the Agent doesn't contain a list of channels they are subscribed too, which means that when calling onDisconnect it seems like one would have to iterate through all channels to check/delete the agent.

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 a pull request may close this issue.

1 participant