summary refs log tree commit diff
diff options
context:
space:
mode:
authorKegan Dougal <kegan@matrix.org>2014-08-15 13:43:07 +0100
committerKegan Dougal <kegan@matrix.org>2014-08-15 14:06:56 +0100
commit7ddb7a5cbbe9e4576742dc060ba35ca863b8d8b0 (patch)
tree395bea9a7d9f95fab285ed9a68d8354dec016ff4
parentStore messages in $rootScope so they can be accessed from multiple controller... (diff)
downloadsynapse-7ddb7a5cbbe9e4576742dc060ba35ca863b8d8b0.tar.xz
Event streaming now happens on an app level, rather than a per-room level. Make eventStreamService manage it's own repolling provided no one calls stop() on it. Couple the stream with eventHandlerService so any controller can just blithely call eventStreamService.resume() and expect to 'get stuff' without having to handle promises (though resume() still returns a promise for that request and proxies it through $q). Kill and reset the stream if you logout.
-rw-r--r--webclient/app-controller.js16
-rw-r--r--webclient/app.js6
-rw-r--r--webclient/components/matrix/event-stream-service.js62
-rw-r--r--webclient/login/login-controller.js7
-rw-r--r--webclient/room/room-controller.js4
5 files changed, 76 insertions, 19 deletions
diff --git a/webclient/app-controller.js b/webclient/app-controller.js
index 086fa3d946..7f5f93ef72 100644
--- a/webclient/app-controller.js
+++ b/webclient/app-controller.js
@@ -21,8 +21,8 @@ limitations under the License.
 'use strict';
 
 angular.module('MatrixWebClientController', ['matrixService'])
-.controller('MatrixWebClientController', ['$scope', '$location', '$rootScope', 'matrixService',
-                               function($scope, $location, $rootScope, matrixService) {
+.controller('MatrixWebClientController', ['$scope', '$location', '$rootScope', 'matrixService', 'eventStreamService',
+                               function($scope, $location, $rootScope, matrixService, eventStreamService) {
          
     // Check current URL to avoid to display the logout button on the login page
     $scope.location = $location.path();
@@ -44,11 +44,15 @@ angular.module('MatrixWebClientController', ['matrixService'])
         else {
             $scope.config = matrixService.config();        
         }
-    };    
-    
+    };
+
+    eventStreamService.resume();
     
     // Logs the user out 
     $scope.logout = function() {
+        // kill the event stream
+        eventStreamService.stop();
+    
         // Clean permanent data
         matrixService.setConfig({});
         matrixService.saveConfig();
@@ -57,7 +61,7 @@ angular.module('MatrixWebClientController', ['matrixService'])
         $location.path("login");
     };
 
-    // Listen to the event indicating that the access token is no more valid.
+    // Listen to the event indicating that the access token is no longer valid.
     // In this case, the user needs to log in again.
     $scope.$on("M_UNKNOWN_TOKEN", function() {
         console.log("Invalid access token -> log user out");
@@ -65,4 +69,4 @@ angular.module('MatrixWebClientController', ['matrixService'])
     });
 }]);
 
-   
\ No newline at end of file
+   
diff --git a/webclient/app.js b/webclient/app.js
index bc78eb9d17..6e0351067f 100644
--- a/webclient/app.js
+++ b/webclient/app.js
@@ -61,12 +61,16 @@ matrixWebClient.config(['$routeProvider', '$provide', '$httpProvider',
         $httpProvider.interceptors.push('AccessTokenInterceptor');
     }]);
 
-matrixWebClient.run(['$location', 'matrixService' , function($location, matrixService) {
+matrixWebClient.run(['$location', 'matrixService', 'eventStreamService', function($location, matrixService, eventStreamService) {
     // If we have no persistent login information, go to the login page
     var config = matrixService.config();
     if (!config || !config.access_token) {
+        eventStreamService.stop();
         $location.path("login");
     }
+    else {
+        eventStreamService.resume();
+    }
 }]);
 
 matrixWebClient
diff --git a/webclient/components/matrix/event-stream-service.js b/webclient/components/matrix/event-stream-service.js
index 1cb9960b9a..97018df881 100644
--- a/webclient/components/matrix/event-stream-service.js
+++ b/webclient/components/matrix/event-stream-service.js
@@ -19,19 +19,21 @@ limitations under the License.
 /*
 This service manages where in the event stream the web client currently is and 
 provides methods to resume/pause/stop the event stream. This service is not
-responsible for parsing event data. For that, see the eventDataHandler.
+responsible for parsing event data. For that, see the eventHandlerService.
 */
 angular.module('eventStreamService', [])
-.factory('eventStreamService', ['matrixService', function(matrixService) {
+.factory('eventStreamService', ['$q', '$timeout', 'matrixService', 'eventHandlerService', function($q, $timeout, matrixService, eventHandlerService) {
     var END = "END";
     var START = "START";
     var TIMEOUT_MS = 5000;
+    var ERR_TIMEOUT_MS = 5000;
     
     var settings = {
         from: "END",
         to: undefined,
         limit: undefined,
-        shouldPoll: true
+        shouldPoll: true,
+        isActive: false
     };
     
     // interrupts the stream. Only valid if there is a stream conneciton 
@@ -39,19 +41,69 @@ angular.module('eventStreamService', [])
     var interrupt = function(shouldPoll) {
         console.log("p[EventStream] interrupt("+shouldPoll+") "+
                     JSON.stringify(settings));
+        settings.shouldPoll = shouldPoll;
+        settings.isActive = false;
     };
     
     var saveStreamSettings = function() {
         localStorage.setItem("streamSettings", JSON.stringify(settings));
     };
     
+    var startEventStream = function() {
+        settings.shouldPoll = true;
+        settings.isActive = true;
+        var deferred = $q.defer();
+        // run the stream from the latest token
+        matrixService.getEventStream(settings.from, TIMEOUT_MS).then(
+            function(response) {
+                if (!settings.isActive) {
+                    console.log("[EventStream] Got response but now inactive. Dropping data.");
+                    return;
+                }
+                
+                settings.from = response.data.end;
+                
+                console.log("[EventStream] Got response from "+settings.from+" to "+response.data.end);
+                eventHandlerService.handleEvents(response.data.chunk, true);
+                
+                deferred.resolve(response);
+                
+                if (settings.shouldPoll) {
+                    $timeout(startEventStream, 0);
+                }
+                else {
+                    console.log("[EventStream] Stopping poll.");
+                }
+            },
+            function(error) {
+                if (error.status == 403) {
+                    settings.shouldPoll = false;
+                }
+                
+                deferred.reject(error);
+                
+                if (settings.shouldPoll) {
+                    $timeout(startEventStream, ERR_TIMEOUT_MS);
+                }
+                else {
+                    console.log("[EventStream] Stopping polling.");
+                }
+            }
+        );
+        return deferred.promise;
+    };
+    
     return {
         // resume the stream from whereever it last got up to. Typically used
         // when the page is opened.
         resume: function() {
+            if (settings.isActive) {
+                console.log("[EventStream] Already active, ignoring resume()");
+                return;
+            }
+        
             console.log("[EventStream] resume "+JSON.stringify(settings));
-            // run the stream from the latest token
-            return matrixService.getEventStream(settings.from, TIMEOUT_MS);
+            return startEventStream();
         },
         
         // pause the stream. Resuming it will continue from the current position
diff --git a/webclient/login/login-controller.js b/webclient/login/login-controller.js
index 8bd6a4e84f..aa928ef48d 100644
--- a/webclient/login/login-controller.js
+++ b/webclient/login/login-controller.js
@@ -1,6 +1,6 @@
 angular.module('LoginController', ['matrixService'])
-.controller('LoginController', ['$scope', '$location', 'matrixService',
-                                    function($scope, $location, matrixService) {
+.controller('LoginController', ['$scope', '$location', 'matrixService', 'eventStreamService',
+                                    function($scope, $location, matrixService, eventStreamService) {
     'use strict';
     
     
@@ -51,7 +51,7 @@ angular.module('LoginController', ['matrixService'])
 
                 // And permanently save it
                 matrixService.saveConfig();
-
+                eventStreamService.resume();
                  // Go to the user's rooms list page
                 $location.path("rooms");
             },
@@ -83,6 +83,7 @@ angular.module('LoginController', ['matrixService'])
                         access_token: response.data.access_token
                     });
                     matrixService.saveConfig();
+                    eventStreamService.resume();
                     $location.path("rooms");
                 }
                 else {
diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js
index 4c5415eace..49c73ff4bb 100644
--- a/webclient/room/room-controller.js
+++ b/webclient/room/room-controller.js
@@ -119,7 +119,6 @@ angular.module('RoomController', [])
                     function(response) {
                         var member = $scope.members[chunk.target_user_id];
                         if (member !== undefined) {
-                            console.log("Updated displayname "+chunk.target_user_id+" to " + response.data.displayname);
                             member.displayname = response.data.displayname;
                         }
                     }
@@ -128,7 +127,6 @@ angular.module('RoomController', [])
                     function(response) {
                          var member = $scope.members[chunk.target_user_id];
                          if (member !== undefined) {
-                            console.log("Updated image for "+chunk.target_user_id+" to " + response.data.avatar_url);
                             member.avatar_url = response.data.avatar_url;
                          }
                     }
@@ -204,8 +202,6 @@ angular.module('RoomController', [])
         matrixService.join($scope.room_id).then(
             function() {
                 console.log("Joined room "+$scope.room_id);
-                // Now start reading from the stream
-                $timeout(shortPoll, 0);
 
                 // Get the current member list
                 matrixService.getMemberList($scope.room_id).then(