Merge pull request #13177 from dotnet-maestro-bot/merge/release/3.0-to-master
[automated] Merge branch 'release/3.0' => 'master'
This commit is contained in:
commit
6699353dc6
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -37,13 +37,8 @@ async function boot(userOptions?: Partial<BlazorOptions>): Promise<void> {
|
|||
}
|
||||
|
||||
const reconnection = existingConnection || await initializeConnection(options, logger);
|
||||
if (reconnection.state !== signalR.HubConnectionState.Connected) {
|
||||
logger.log(LogLevel.Information, 'Reconnection attempt failed. Unable to connect to the server.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(await circuit.reconnect(reconnection))) {
|
||||
logger.log(LogLevel.Information, 'Reconnection attempt to the circuit failed.');
|
||||
logger.log(LogLevel.Information, 'Reconnection attempt to the circuit was rejected by the server. This may indicate that the associated state is no longer available on the server.');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ReconnectDisplay } from './ReconnectDisplay';
|
||||
import { Logger, LogLevel } from '../Logging/Logger';
|
||||
|
||||
export class DefaultReconnectDisplay implements ReconnectDisplay {
|
||||
modal: HTMLDivElement;
|
||||
|
|
@ -11,7 +12,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
|
|||
|
||||
reloadParagraph: HTMLParagraphElement;
|
||||
|
||||
constructor(dialogId: string, private document: Document) {
|
||||
constructor(dialogId: string, private readonly document: Document, private readonly logger: Logger) {
|
||||
this.modal = this.document.createElement('div');
|
||||
this.modal.id = dialogId;
|
||||
|
||||
|
|
@ -38,8 +39,19 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
|
|||
|
||||
this.button.addEventListener('click', async () => {
|
||||
this.show();
|
||||
const successful = await window['Blazor'].reconnect();
|
||||
if (!successful) {
|
||||
|
||||
try {
|
||||
// reconnect will asynchronously return:
|
||||
// - true to mean success
|
||||
// - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
|
||||
// - exception to mean we didn't reach the server (this can be sync or async)
|
||||
const successful = await window['Blazor'].reconnect();
|
||||
if (!successful) {
|
||||
this.rejected();
|
||||
}
|
||||
} catch (err) {
|
||||
// We got an exception, server is currently unavailable
|
||||
this.logger.log(LogLevel.Error, err);
|
||||
this.failed();
|
||||
}
|
||||
});
|
||||
|
|
@ -66,4 +78,10 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
|
|||
this.reloadParagraph.style.display = 'none';
|
||||
this.message.innerHTML = 'Reconnection failed. Try <a href>reloading</a> the page if you\'re unable to reconnect.';
|
||||
}
|
||||
|
||||
rejected(): void {
|
||||
this.button.style.display = 'none';
|
||||
this.reloadParagraph.style.display = 'none';
|
||||
this.message.innerHTML = 'Could not reconnect to the server. <a href>Reload</a> the page to restore functionality.';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export class DefaultReconnectionHandler implements ReconnectionHandler {
|
|||
const modal = document.getElementById(options.dialogId);
|
||||
this._reconnectionDisplay = modal
|
||||
? new UserSpecifiedDisplay(modal)
|
||||
: new DefaultReconnectDisplay(options.dialogId, document);
|
||||
: new DefaultReconnectDisplay(options.dialogId, document, this._logger);
|
||||
}
|
||||
|
||||
if (!this._currentReconnectionProcess) {
|
||||
|
|
@ -67,7 +67,8 @@ class ReconnectionProcess {
|
|||
const result = await this.reconnectCallback();
|
||||
if (!result) {
|
||||
// If the server responded and refused to reconnect, stop auto-retrying.
|
||||
break;
|
||||
this.reconnectDisplay.rejected();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ export interface ReconnectDisplay {
|
|||
show(): void;
|
||||
hide(): void;
|
||||
failed(): void;
|
||||
rejected(): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
|
|||
|
||||
static readonly FailedClassName = 'components-reconnect-failed';
|
||||
|
||||
static readonly RefusedClassName = 'components-reconnect-refused';
|
||||
|
||||
constructor(private dialog: HTMLElement) {
|
||||
}
|
||||
|
||||
|
|
@ -23,8 +25,13 @@ export class UserSpecifiedDisplay implements ReconnectDisplay {
|
|||
this.removeClasses();
|
||||
this.dialog.classList.add(UserSpecifiedDisplay.FailedClassName);
|
||||
}
|
||||
|
||||
rejected(): void {
|
||||
this.removeClasses();
|
||||
this.dialog.classList.add(UserSpecifiedDisplay.RefusedClassName);
|
||||
}
|
||||
|
||||
private removeClasses() {
|
||||
this.dialog.classList.remove(UserSpecifiedDisplay.ShowClassName, UserSpecifiedDisplay.HideClassName, UserSpecifiedDisplay.FailedClassName);
|
||||
this.dialog.classList.remove(UserSpecifiedDisplay.ShowClassName, UserSpecifiedDisplay.HideClassName, UserSpecifiedDisplay.FailedClassName, UserSpecifiedDisplay.RefusedClassName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { DefaultReconnectDisplay } from "../src/Platform/Circuits/DefaultReconnectDisplay";
|
||||
import {JSDOM} from 'jsdom';
|
||||
import { NullLogger} from '../src/Platform/Logging/Loggers';
|
||||
|
||||
describe('DefaultReconnectDisplay', () => {
|
||||
|
||||
it ('adds element to the body on show', () => {
|
||||
const testDocument = new JSDOM().window.document;
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument);
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument, NullLogger.instance);
|
||||
|
||||
display.show();
|
||||
|
||||
|
|
@ -20,7 +21,7 @@ describe('DefaultReconnectDisplay', () => {
|
|||
|
||||
it ('does not add element to the body multiple times', () => {
|
||||
const testDocument = new JSDOM().window.document;
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument);
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument, NullLogger.instance);
|
||||
|
||||
display.show();
|
||||
display.show();
|
||||
|
|
@ -30,7 +31,7 @@ describe('DefaultReconnectDisplay', () => {
|
|||
|
||||
it ('hides element', () => {
|
||||
const testDocument = new JSDOM().window.document;
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument);
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument, NullLogger.instance);
|
||||
|
||||
display.hide();
|
||||
|
||||
|
|
@ -39,7 +40,7 @@ describe('DefaultReconnectDisplay', () => {
|
|||
|
||||
it ('updates message on fail', () => {
|
||||
const testDocument = new JSDOM().window.document;
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument);
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument, NullLogger.instance);
|
||||
|
||||
display.show();
|
||||
display.failed();
|
||||
|
|
@ -49,4 +50,16 @@ describe('DefaultReconnectDisplay', () => {
|
|||
expect(display.button.style.display).toBe('block');
|
||||
});
|
||||
|
||||
it ('updates message on refused', () => {
|
||||
const testDocument = new JSDOM().window.document;
|
||||
const display = new DefaultReconnectDisplay('test-dialog-id', testDocument, NullLogger.instance);
|
||||
|
||||
display.show();
|
||||
display.rejected();
|
||||
|
||||
expect(display.modal.style.display).toBe('block');
|
||||
expect(display.message.innerHTML).toBe('Could not reconnect to the server. <a href=\"\">Reload</a> the page to restore functionality.');
|
||||
expect(display.button.style.display).toBe('none');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ function createTestDisplay(): ReconnectDisplay {
|
|||
return {
|
||||
show: jest.fn(),
|
||||
hide: jest.fn(),
|
||||
failed: jest.fn()
|
||||
failed: jest.fn(),
|
||||
rejected: jest.fn()
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue