瀏覽代碼

[RN] Fix processing outdated loadConfig requests (continued)

Co-authored-by: Lyubo Marinov <lmarinov@atlassian.com>
Co-authored-by: Paweł Domas <pawel.domas@jitsi.org>
master
Lyubo Marinov 7 年之前
父節點
當前提交
592305df74

+ 29
- 25
react/features/app/actions.js 查看文件

@@ -1,4 +1,4 @@
1
-/* @flow */
1
+// @flow
2 2
 
3 3
 import type { Dispatch } from 'redux';
4 4
 
@@ -51,8 +51,9 @@ function _appNavigateToMandatoryLocation(
51 51
         newLocation: Object
52 52
 ): Promise<void> {
53 53
     const { room } = newLocation;
54
+    const locationURL = new URL(newLocation.toString());
54 55
 
55
-    dispatch(configWillLoad(newLocation));
56
+    dispatch(configWillLoad(locationURL));
56 57
 
57 58
     return (
58 59
         _loadConfig(dispatch, getState, newLocation)
@@ -73,33 +74,32 @@ function _appNavigateToMandatoryLocation(
73 74
      * @returns {void}
74 75
      */
75 76
     function loadConfigSettled(error, config) {
76
-        // Due to the asynchronous nature of the loading, the specified
77
-        // config may or may not be required by the time the notification
78
-        // arrives. If we receive the config for a location we are no longer
79
-        // interested in, just dump it.
80
-
81
-        const { locationURL: currentLocationURL }
82
-            = getState()['features/base/config'];
83
-
84
-        if (currentLocationURL !== newLocation) {
85
-            throw new Error('Config no longer needed');
77
+        let promise;
78
+
79
+        // Due to the asynchronous nature of the loading, the specified config
80
+        // may or may not be required by the time the notification arrives.
81
+        // If we receive the config for a location we are no longer interested
82
+        // in, "ignore" it - deliver it to the external API, for example, but do
83
+        // not proceed with the appNavigate procedure/process.
84
+        if (getState()['features/base/config'].locationURL === locationURL) {
85
+            promise = dispatch(setLocationURL(locationURL));
86
+        } else {
87
+            // eslint-disable-next-line no-param-reassign
88
+            error || (error = new Error('Config no longer needed!'));
89
+            promise = Promise.resolve();
86 90
         }
87 91
 
88
-        const promise
89
-            = dispatch(setLocationURL(new URL(newLocation.toString())));
90
-
91
-        if (error) {
92
-            // XXX The failure could be, for example, because of a
93
-            // certificate-related error. In which case the connection will
94
-            // fail later in Strophe anyway.
95
-            return promise.then(() => {
96
-                dispatch(loadConfigError(error, newLocation));
92
+        return promise.then(() => {
93
+            if (error) {
94
+                // XXX The failure could be, for example, because of a
95
+                // certificate-related error. In which case the connection will
96
+                // fail later in Strophe anyway.
97
+                dispatch(loadConfigError(error, locationURL));
97 98
                 throw error;
98
-            });
99
-        }
99
+            }
100 100
 
101
-        return promise.then(() =>
102
-            dispatch(setConfig(config)));
101
+            return dispatch(setConfig(config));
102
+        });
103 103
     }
104 104
 }
105 105
 
@@ -227,6 +227,10 @@ function _loadConfig(
227 227
 
228 228
     return loadConfig(url).then(
229 229
         /* onFulfilled */ config => {
230
+            // FIXME If the config is no longer needed (in the terms of
231
+            // _loadConfig) and that happened because of an intervening
232
+            // _loadConfig for the same baseURL, then the unneeded config may be
233
+            // stored after the needed config. Anyway.
230 234
             dispatch(storeConfig(baseURL, config));
231 235
 
232 236
             return config;

+ 6
- 6
react/features/base/config/actionTypes.js 查看文件

@@ -1,22 +1,22 @@
1 1
 /**
2
- * The redux action which signals that a configuration will be loaded for a
3
- * specific locationURL.
2
+ * The redux action which signals that a configuration (commonly known in Jitsi
3
+ * Meet as config.js) will be loaded for a specific locationURL.
4 4
  *
5 5
  * {
6 6
  *     type: CONFIG_WILL_LOAD,
7
- *     locationURL: string | URL
7
+ *     locationURL: URL
8 8
  * }
9 9
  */
10 10
 export const CONFIG_WILL_LOAD = Symbol('CONFIG_WILL_LOAD');
11 11
 
12 12
 /**
13
- * The redux action which signals that a configuration could not be loaded due
14
- * to a specific error.
13
+ * The redux action which signals that a configuration (commonly known in Jitsi
14
+ * Meet as config.js) could not be loaded due to a specific error.
15 15
  *
16 16
  * {
17 17
  *     type: LOAD_CONFIG_ERROR,
18 18
  *     error: Error,
19
- *     locationURL: string | URL
19
+ *     locationURL: URL
20 20
  * }
21 21
  */
22 22
 export const LOAD_CONFIG_ERROR = Symbol('LOAD_CONFIG_ERROR');

+ 13
- 15
react/features/base/config/actions.js 查看文件

@@ -5,25 +5,22 @@ import type { Dispatch } from 'redux';
5 5
 import { addKnownDomains } from '../known-domains';
6 6
 import { parseURIString } from '../util';
7 7
 
8
-import {
9
-    CONFIG_WILL_LOAD,
10
-    LOAD_CONFIG_ERROR,
11
-    SET_CONFIG
12
-} from './actionTypes';
8
+import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
13 9
 import { _CONFIG_STORE_PREFIX } from './constants';
14 10
 import { setConfigFromURLParams } from './functions';
15 11
 
16 12
 /**
17
- * Signals that the configuration for a specific locationURL will be loaded now.
13
+ * Signals that the configuration (commonly known in Jitsi Meet as config.js)
14
+ * for a specific locationURL will be loaded now.
18 15
  *
19
- * @param {string|URL} locationURL - The URL of the location which necessitated
20
- * the loading of a configuration.
16
+ * @param {URL} locationURL - The URL of the location which necessitated the
17
+ * loading of a configuration.
21 18
  * @returns {{
22 19
  *     type: CONFIG_WILL_LOAD,
23
- *     locationURL
20
+ *     locationURL: URL
24 21
  * }}
25 22
  */
26
-export function configWillLoad(locationURL: string | URL) {
23
+export function configWillLoad(locationURL: URL) {
27 24
     return {
28 25
         type: CONFIG_WILL_LOAD,
29 26
         locationURL
@@ -31,19 +28,20 @@ export function configWillLoad(locationURL: string | URL) {
31 28
 }
32 29
 
33 30
 /**
34
- * Signals that a configuration could not be loaded due to a specific error.
31
+ * Signals that a configuration (commonly known in Jitsi Meet as config.js)
32
+ * could not be loaded due to a specific error.
35 33
  *
36 34
  * @param {Error} error - The {@code Error} which prevented the successful
37 35
  * loading of a configuration.
38
- * @param {string|URL} locationURL - The URL of the location which necessitated
39
- * the loading of a configuration.
36
+ * @param {URL} locationURL - The URL of the location which necessitated the
37
+ * loading of a configuration.
40 38
  * @returns {{
41 39
  *     type: LOAD_CONFIG_ERROR,
42 40
  *     error: Error,
43
- *     locationURL
41
+ *     locationURL: URL
44 42
  * }}
45 43
  */
46
-export function loadConfigError(error: Error, locationURL: string | URL) {
44
+export function loadConfigError(error: Error, locationURL: URL) {
47 45
     return {
48 46
         type: LOAD_CONFIG_ERROR,
49 47
         error,

+ 29
- 12
react/features/base/config/reducer.js 查看文件

@@ -1,14 +1,10 @@
1
-/* @flow */
1
+// @flow
2 2
 
3 3
 import _ from 'lodash';
4 4
 
5 5
 import { equals, ReducerRegistry, set } from '../redux';
6 6
 
7
-import {
8
-    CONFIG_WILL_LOAD,
9
-    LOAD_CONFIG_ERROR,
10
-    SET_CONFIG
11
-} from './actionTypes';
7
+import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
12 8
 
13 9
 /**
14 10
  * The initial state of the feature base/config when executing in a
@@ -54,20 +50,41 @@ ReducerRegistry.register(
54 50
         case CONFIG_WILL_LOAD:
55 51
             return {
56 52
                 error: undefined,
53
+
54
+                /**
55
+                 * The URL of the location associated with/configured by this
56
+                 * configuration.
57
+                 *
58
+                 * @type URL
59
+                 */
57 60
                 locationURL: action.locationURL
58 61
             };
59 62
 
60 63
         case LOAD_CONFIG_ERROR:
61
-            return {
62
-                error: action.error
63
-            };
64
+            // XXX LOAD_CONFIG_ERROR is one of the settlement execution paths of
65
+            // the asynchronous "loadConfig procedure/process" started with
66
+            // CONFIG_WILL_LOAD. Due to the asynchronous nature of it, whoever
67
+            // is settling the process needs to provide proof that they have
68
+            // started it and that the iteration of the process being completed
69
+            // now is still of interest to the app.
70
+            if (state.locationURL === action.locationURL) {
71
+                return {
72
+                    /**
73
+                     * The {@link Error} which prevented the loading of the
74
+                     * configuration of the associated {@code locationURL}.
75
+                     *
76
+                     * @type Error
77
+                     */
78
+                    error: action.error
79
+                };
80
+            }
81
+            break;
64 82
 
65 83
         case SET_CONFIG:
66 84
             return _setConfig(state, action);
67
-
68
-        default:
69
-            return state;
70 85
         }
86
+
87
+        return state;
71 88
     });
72 89
 
73 90
 /**

+ 11
- 7
react/features/mobile/external-api/middleware.js 查看文件

@@ -28,8 +28,9 @@ import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
28 28
  */
29 29
 MiddlewareRegistry.register(store => next => action => {
30 30
     const result = next(action);
31
+    const { type } = action;
31 32
 
32
-    switch (action.type) {
33
+    switch (type) {
33 34
     case CONFERENCE_FAILED: {
34 35
         const { error, ...data } = action;
35 36
 
@@ -64,16 +65,19 @@ MiddlewareRegistry.register(store => next => action => {
64 65
         break;
65 66
 
66 67
     case ENTER_PICTURE_IN_PICTURE:
67
-        _sendEvent(store, _getSymbolDescription(action.type), /* data */ {});
68
+        _sendEvent(store, _getSymbolDescription(type), /* data */ {});
68 69
         break;
69 70
 
70 71
     case LOAD_CONFIG_ERROR: {
71
-        const { error, locationURL, type } = action;
72
+        const { error, locationURL } = action;
72 73
 
73
-        _sendEvent(store, _getSymbolDescription(type), /* data */ {
74
-            error: _toErrorString(error),
75
-            url: toURLString(locationURL)
76
-        });
74
+        _sendEvent(
75
+            store,
76
+            _getSymbolDescription(type),
77
+            /* data */ {
78
+                error: _toErrorString(error),
79
+                url: toURLString(locationURL)
80
+            });
77 81
         break;
78 82
     }
79 83
 

Loading…
取消
儲存