Merge pull request #4540 from FinnStutzenstein/trackFirefoxIssues

Track storage fallbacks via count users
This commit is contained in:
Finn Stutzenstein 2019-04-01 08:49:55 +02:00 committed by GitHub
commit 55c162809c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 16 deletions

View File

@ -66,7 +66,7 @@ export class CustomIndexedDBDatabase extends IndexedDBDatabase {
} else {
// Storing the database connection for further access
this.database.next(db);
this.storageLock.OK();
this.storageLock.OK(true);
}
},
() => {
@ -80,7 +80,7 @@ export class CustomIndexedDBDatabase extends IndexedDBDatabase {
public setFallback(prefix: string): void {
console.log('uses localStorage as IndexedDB fallback!');
super.setFallback(prefix);
this.storageLock.OK();
this.storageLock.OK(false);
}
}

View File

@ -9,16 +9,22 @@ import { Injectable } from '@angular/core';
export class StoragelockService {
private lock: Promise<void>;
private resolve: () => void;
private _indexedDBUsed = false;
public get promise(): Promise<void> {
return this.lock;
}
public get indexedDBUsed(): boolean {
return this._indexedDBUsed;
}
public constructor() {
this.lock = new Promise<void>(resolve => (this.resolve = resolve));
}
public OK(): void {
public OK(indexedDBUsed: boolean): void {
this._indexedDBUsed = indexedDBUsed;
this.resolve();
}
}

View File

@ -4,13 +4,19 @@ import { Observable, Subject } from 'rxjs';
import { NotifyService } from '../core-services/notify.service';
import { OperatorService } from '../core-services/operator.service';
import { StoragelockService } from '../local-storage/storagelock.service';
interface CountUserRequest {
token: string;
}
interface CountUserResponse extends CountUserRequest {
export interface CountUserData {
userId: number;
usesIndexedDB: boolean;
}
interface CountUserResponse extends CountUserRequest {
data: CountUserData;
}
const REQUEST_NAME = 'count-user-request';
@ -25,7 +31,7 @@ const RESPONSE_NAME = 'count-user-response';
providedIn: 'root'
})
export class CountUsersService {
private activeCounts: { [token: string]: Subject<number> } = {};
private activeCounts: { [token: string]: Subject<CountUserData> } = {};
private currentUserId: number;
@ -35,15 +41,22 @@ export class CountUsersService {
* @param notifyService
* @param operator
*/
public constructor(private notifyService: NotifyService, operator: OperatorService) {
public constructor(
private notifyService: NotifyService,
operator: OperatorService,
storageLockService: StoragelockService
) {
// Listen for requests to send an answer.
this.notifyService.getMessageObservable<CountUserRequest>(REQUEST_NAME).subscribe(request => {
if (request.content.token) {
this.notifyService.sendToChannels(
this.notifyService.sendToChannels<CountUserResponse>(
RESPONSE_NAME,
{
token: request.content.token,
userId: this.currentUserId
data: {
userId: this.currentUserId,
usesIndexedDB: storageLockService.indexedDBUsed
}
},
request.senderChannelName
);
@ -52,8 +65,8 @@ export class CountUsersService {
// Listen for responses and distribute them through `activeCounts`
this.notifyService.getMessageObservable<CountUserResponse>(RESPONSE_NAME).subscribe(response => {
if (response.content.userId && response.content.token && this.activeCounts[response.content.token]) {
this.activeCounts[response.content.token].next(response.content.userId);
if (response.content.data && response.content.token && this.activeCounts[response.content.token]) {
this.activeCounts[response.content.token].next(response.content.data);
}
});
@ -80,9 +93,9 @@ export class CountUsersService {
* counting with `stopCounting`. The second entry is an observable, where all user
* ids will be published.
*/
public countUsers(): [string, Observable<number>] {
public countUsers(): [string, Observable<CountUserData>] {
const trackToken = this.generateTrackToken();
const subject = new Subject<number>();
const subject = new Subject<CountUserData>();
this.activeCounts[trackToken] = subject;
this.notifyService.sendToAllUsers<CountUserRequest>(REQUEST_NAME, {
token: trackToken

View File

@ -8,6 +8,8 @@
<div *ngIf="stats">
<p>
{{ userIds().length }} <span translate>active users</span>
({{ stats.usesIndexedDB }} <span translate>with indexedDB</span>,
{{ stats.activeUserHandles-stats.usesIndexedDB }} <span translate>with local storage</span>)
({{ stats.activeUserHandles }} <span translate>connections</span>)
</p>
<h3 translate>Groups</h3>

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { CountUsersService } from 'app/core/ui-services/count-users.service';
import { CountUsersService, CountUserData } from 'app/core/ui-services/count-users.service';
import { Observable, BehaviorSubject } from 'rxjs';
import { UserRepositoryService } from 'app/core/repositories/users/user-repository.service';
@ -9,6 +9,7 @@ import { UserRepositoryService } from 'app/core/repositories/users/user-reposito
*/
export interface CountUserStatistics {
activeUserHandles: number;
usesIndexedDB: number;
activeUsers: {
[id: number]: number;
};
@ -42,25 +43,31 @@ export class CountUsersStatisticsService {
*/
public countUsers(): [string, Observable<CountUserStatistics>] {
let token: string;
let userIdObservable: Observable<number>;
let userDataObservable: Observable<CountUserData>;
// Start counting
// TODO: maybe we shold bet the observable bofore the actual countig was
// started. We might miss some user ids.
[token, userIdObservable] = this.countUserService.countUsers();
[token, userDataObservable] = this.countUserService.countUsers();
this.runningCounts[token] = new BehaviorSubject<CountUserStatistics>({
activeUserHandles: 0,
usesIndexedDB: 0,
activeUsers: {},
groups: {}
});
// subscribe to responses
userIdObservable.subscribe(userId => {
userDataObservable.subscribe(data => {
const userId = !!data.userId ? data.userId : 0;
const stats = this.runningCounts[token].getValue();
const user = this.userRepo.getViewModel(userId);
// Add to user stats
stats.activeUserHandles++;
if (data.usesIndexedDB) {
stats.usesIndexedDB++;
}
if (!stats.activeUsers[userId]) {
stats.activeUsers[userId] = 0;
}