From e8dff2005d5ff173d701f03e34dd043ee314b1ec Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Wed, 18 Feb 2015 17:41:18 -0800 Subject: [PATCH] fix(streaming): A few minor fixes for login/logout --- .../lib/account-sidebar-store.coffee | 2 + .../lib/activity-bar-store.coffee | 5 ++ src/flux/inbox-api.coffee | 82 +++++++++++-------- src/flux/inbox-long-connection.coffee | 10 ++- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/internal_packages/account-sidebar/lib/account-sidebar-store.coffee b/internal_packages/account-sidebar/lib/account-sidebar-store.coffee index e68931c55..693da9674 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar-store.coffee +++ b/internal_packages/account-sidebar/lib/account-sidebar-store.coffee @@ -55,6 +55,8 @@ AccountSidebarStore = Reflux.createStore _populateUnreadCounts: -> namespace = NamespaceStore.current() + return unless namespace + @_sections.forEach (section) => section.tags.forEach (tag) => # Some tags don't have unread counts diff --git a/internal_packages/inbox-activity-bar/lib/activity-bar-store.coffee b/internal_packages/inbox-activity-bar/lib/activity-bar-store.coffee index 1be756a4e..368f3ad60 100644 --- a/internal_packages/inbox-activity-bar/lib/activity-bar-store.coffee +++ b/internal_packages/inbox-activity-bar/lib/activity-bar-store.coffee @@ -27,6 +27,11 @@ ActivityBarStore = Reflux.createStore @listenTo Actions.didMakeAPIRequest, @_onAPIRequest @listenTo Actions.developerPanelSelectSection, @_onSelectSection @listenTo Actions.longPollStateChanged, @_onLongPollStateChange + @listenTo Actions.logout, @_onLogout + + _onLogout: -> + @_setStoreDefaults() + @trigger(@) _onSelectSection: (section) -> @_section = section diff --git a/src/flux/inbox-api.coffee b/src/flux/inbox-api.coffee index 2cb86556d..07fef4ec5 100644 --- a/src/flux/inbox-api.coffee +++ b/src/flux/inbox-api.coffee @@ -3,6 +3,7 @@ request = require 'request' Actions = require './actions' {APIError} = require './errors' DatabaseStore = require './stores/database-store' +NamespaceStore = require './stores/namespace-store' InboxLongConnection = require './inbox-long-connection' {modelFromJSON, modelClassMap} = require './models/utils' async = require 'async' @@ -10,10 +11,13 @@ async = require 'async' class InboxAPI constructor: -> - @APILongConnections = {} + @_streamingConnections = [] atom.config.onDidChange('inbox.env', @_onConfigChanged) atom.config.onDidChange('inbox.token', @_onConfigChanged) @_onConfigChanged() + + NamespaceStore.listen(@_onNamespacesChanged, @) + @_onNamespacesChanged() @ _onConfigChanged: => @@ -30,50 +34,60 @@ class InboxAPI current = {@APIToken, @AppID, @APIRoot} - if atom.state.mode is 'editor' and not _.isEqual(prev, current) - @makeRequest - path: "/n" - returnsModel: true - success: => - @_startLongPolling() - error: => - @_startLongPolling() + if atom.state.mode is 'editor' + if not @APIToken? + @_closeStreamingConnections() - _stopLongPolling: -> - for namespace, connection of @APILongConnections - connection.end() - @APILongConnections = {} + if not _.isEqual(prev, current) + @makeRequest + path: "/n" + returnsModel: true - _startLongPolling: -> - return unless atom.state.mode == 'editor' + console.log(@_streamingConnections.length) + + _onNamespacesChanged: -> + return unless atom.state.mode is 'editor' return if atom.getLoadSettings().isSpec + + namespaces = NamespaceStore.items() + connections = _.map(namespaces, @_streamingConnectionForNamespace) - DatabaseStore = require './stores/database-store' - Namespace = require './models/namespace' + # Close the connections that are not in the new connections list. + # These namespaces are no longer in our database, so we shouldn't + # be listening. + old = _.without(@_streamingConnections, connections...) + conn.end() for conn in old - DatabaseStore.findAll(Namespace).then (namespaces) => - @_stopLongPolling() + @_streamingConnections = connections - namespaces.forEach (namespace) => - connection = new InboxLongConnection(@, namespace.id) - @APILongConnections[namespace.id] = connection + _closeStreamingConnections: -> + for conn in @_streamingConnections + conn.end() + @_streamingConnections = [] - if !connection.hasCursor() - @getThreads(namespace.id) - @getCalendars(namespace.id) + _streamingConnectionForNamespace: (namespace) => + connection = _.find @_streamingConnections, (c) -> + c.namespaceId() is namespace.id + console.log('Found existing connection') if connection + return connection if connection - connection.onStateChange (state) -> - Actions.longPollStateChanged(state) - if state == InboxLongConnection.State.Connected - Actions.restartTaskQueue() + connection = new InboxLongConnection(@, namespace.id) - connection.onDeltas (deltas) => - @_handleDeltas(namespace.id, deltas) - Actions.restartTaskQueue() + if !connection.hasCursor() + @getThreads(namespace.id) + @getCalendars(namespace.id) - connection.start() + connection.onStateChange (state) -> + Actions.longPollStateChanged(state) + if state == InboxLongConnection.State.Connected + Actions.restartTaskQueue() - .catch (error) -> console.error(error) + connection.onDeltas (deltas) => + @_handleDeltas(namespace.id, deltas) + Actions.restartTaskQueue() + + connection.start() + connection # Delegates to node's request object. # On success, it will call the passed in success callback with options. diff --git a/src/flux/inbox-long-connection.coffee b/src/flux/inbox-long-connection.coffee index d02135d3f..ad9e542bd 100644 --- a/src/flux/inbox-long-connection.coffee +++ b/src/flux/inbox-long-connection.coffee @@ -6,6 +6,7 @@ class InboxLongConnection @State = Idle: 'idle' + Ended: 'ended' Connecting: 'connecting' Connected: 'connected' Retrying: 'retrying' @@ -27,7 +28,10 @@ class InboxLongConnection , 1000 @ - + + namespaceId: -> + @_namespaceId + hasCursor: -> !!atom.config.get(@_cursorKey) @@ -85,7 +89,9 @@ class InboxLongConnection throw (new Error 'Cannot start polling without auth token.') unless @_inbox.APIToken return if @_req + console.log("Long Polling Connection: Starting....") @withCursor (cursor) => + return if @state is InboxLongConnection.State.Ended console.log("Long Polling Connection: Starting for namespace #{@_namespaceId}, token #{@_inbox.APIToken}, with cursor #{cursor}") options = url.parse("#{@_inbox.APIRoot}/n/#{@_namespaceId}/delta/streaming?cursor=#{cursor}&exclude_types=event") options.auth = "#{@_inbox.APIToken}:" @@ -129,7 +135,7 @@ class InboxLongConnection end: -> console.log("Long Polling Connection: Closed.") - @setState(InboxLongConnection.State.Idle) + @setState(InboxLongConnection.State.Ended) clearInterval(@_reqPingInterval) if @_reqPingInterval @_reqPingInterval = null @_req.end() if @_req