add name debug info to fetchable-pair-verifier

This commit is contained in:
Michael Peters 2022-10-25 22:53:02 -07:00
parent 366022cebb
commit 6e95ec4cec
7 changed files with 26 additions and 30 deletions

View File

@ -27,6 +27,7 @@ export class AutoVerifierWithArg<T, K> {
private primaryFunc: (query: K) => Promise<T | null>,
private trustedFunc: (query: K) => Promise<T | null>,
private verifyFunc: (query: K, primaryResult: T | null, trustedResult: T | null) => Promise<boolean>,
private name: string | null = null, // for debugging purposes
) {}
static createStandardPartialMessageListAutoVerifier<T extends WithEquals<T> & { id: string }>(
@ -37,6 +38,7 @@ export class AutoVerifierWithArg<T, K> {
changesType: AutoVerifierChangesType,
changes: Changes<T>,
) => Promise<boolean>,
name: string | null = null,
) {
return new AutoVerifierWithArg<T[], PartialMessageListQuery>(
query => `ch#${query.channelId} mo#${query.messageOrderId}->${query.number}`,
@ -57,6 +59,7 @@ export class AutoVerifierWithArg<T, K> {
const changesType = AutoVerifier.getListChangesType<T>(primaryResult, trustedResult, changes);
return await changesFunc(query, changesType, changes);
},
name,
);
}
@ -69,6 +72,7 @@ export class AutoVerifierWithArg<T, K> {
primaryResult: T | null,
trustedResult: T | null,
) => Promise<boolean>,
name: string | null = null,
) {
return new AutoVerifierWithArg<T, IDQuery>(
query => `id#${query.id}`,
@ -78,6 +82,7 @@ export class AutoVerifierWithArg<T, K> {
const changesType = AutoVerifier.getSingleChangesType<T>(primaryResult, trustedResult);
return await changesFunc(query, changesType, primaryResult, trustedResult);
},
name,
);
}
@ -117,6 +122,7 @@ export class AutoVerifierWithArg<T, K> {
async () => await this.trustedFunc(query),
async (primaryResult: T | null, trustedResult: T | null) =>
await this.verifyFunc(query, primaryResult, trustedResult),
`${this.name}::${token.slice(0, 8)}`
);
this.tokenAutoVerifiers.set(token, autoVerifier);
}

View File

@ -254,7 +254,7 @@ export class AutoVerifier<T> {
// we've been invalidated while we were waiting for the trusted result!
// TODO: This happens when a socket fetch is sent before the socket is connected to.
console.warn(
'RARE ALERT: we got unverified while trying to fetch a trusted promise for verification!',
`RARE ALERT: ${this.name || 'we'} got unverified while trying to fetch a trusted promise for verification!`,
new Error(),
);
if (this.trustedPromise === null) {
@ -281,8 +281,6 @@ export class AutoVerifier<T> {
this.trustedPromise = null;
}
} else {
// this actually could be quite common
//console.warn('RARE ALERT: we got unverified during verification!');
// ** complexity:
// if primaryUpToDate is false or we got unverified during verification, this path will still return
// the trustedResult that was passed to the verify function
@ -320,7 +318,7 @@ export class AutoVerifier<T> {
if (this.trustedPromise !== origTrustedPromise) {
// we've been invalidated while we were waiting for the trusted result!
console.warn(
'ULTRA RARE ALERT: we got unverified while awaiting a trusted promise another path was verifying!',
`ULTRA RARE ALERT: ${this.name || 'we'} got unverified while awaiting a trusted promise another path was verifying!`,
);
await tryResolveTrustedPromise();
return;
@ -330,7 +328,7 @@ export class AutoVerifier<T> {
if (this.trustedPromise !== origTrustedPromise) {
// we've been invalidated while we were waiting for the verify!
console.warn(
'ULTRA RARE ALERT: we got unverified while awaiting a verify promise another path was calling!',
`ULTRA RARE ALERT: ${this.name || 'we'} got unverified while awaiting a verify promise another path was calling!`,
);
// ** complexity:
// if primaryUpToDate is false or we got unverified during verification, this path will still return

View File

@ -4,13 +4,13 @@ import Logger from '../../logger/logger';
const LOG = Logger.create(__filename, electronConsole);
import { Changes, Channel, GuildMetadata, Member, Message, Resource, Token } from './data-types';
import { AsyncFetchable, Fetchable, Lackable, Conflictable, Ensurable } from './guild-types';
import { AsyncFetchable, Fetchable, Lackable, Conflictable } from './guild-types';
import { AutoVerifier, AutoVerifierChangesType } from './auto-verifier';
import { AutoVerifierWithArg, PartialMessageListQuery, IDQuery } from './auto-verifier-with-args';
import { EventEmitter } from 'tsee';
/** uses a primary fetchable and trusted fetchable and verifys the results. Can be chained together with itself as a trusted fetchable! */
export default class PairVerifierFetchable extends EventEmitter<Conflictable> implements AsyncFetchable, Ensurable {
export default class PairVerifierFetchable extends EventEmitter<Conflictable> implements AsyncFetchable {
private readonly fetchMetadataVerifier: AutoVerifier<GuildMetadata>;
private readonly fetchMembersVerifier: AutoVerifier<Member[]>;
private readonly fetchChannelsVerifier: AutoVerifier<Channel[]>;
@ -22,7 +22,7 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
public readonly fetchMessagesBeforeVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>;
public readonly fetchMessagesAfterVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>;
constructor(private primary: Fetchable & Lackable, private trusted: Fetchable & Ensurable, private name: string | null = null) {
constructor(private primary: Fetchable & Lackable, private trusted: Fetchable, private name: string | null = null) {
super();
if (trusted instanceof PairVerifierFetchable) {
@ -39,18 +39,21 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
async () => await this.primary.fetchMetadata(),
async () => await this.trusted.fetchMetadata(),
this.handleMetadataConflict.bind(this),
`${this.name}#fetchMetadata`,
);
this.fetchMembersVerifier = AutoVerifier.createStandardListAutoVerifier<Member>(
async () => await this.primary.fetchMembers(),
async () => await this.trusted.fetchMembers(),
this.handleMembersConflict.bind(this),
`${this.name}#fetchMembers`,
);
this.fetchChannelsVerifier = AutoVerifier.createStandardListAutoVerifier<Channel>(
async () => await this.primary.fetchChannels(),
async () => await this.trusted.fetchChannels(),
this.handleChannelsConflict.bind(this),
`${this.name}#fetchChannels`,
);
this.fetchTokensVerifier = AutoVerifier.createStandardListAutoVerifier<Token>(
@ -59,12 +62,14 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
async () => await this.primary.fetchTokens(),
async () => await this.trusted.fetchTokens(),
this.handleTokensConflict.bind(this),
`${this.name}#fetchTokens`,
);
this.fetchResourceVerifier = AutoVerifierWithArg.createStandardIDQueriedSingleAutoVerifier<Resource>(
async (query: IDQuery) => await this.primary.fetchResource(query.id),
async (query: IDQuery) => await this.trusted.fetchResource(query.id),
this.handleResourceConflict.bind(this),
`${this.name}#fetchResource`,
);
this.fetchMessagesRecentVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier(
@ -73,6 +78,7 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
async (query: PartialMessageListQuery) =>
await this.trusted.fetchMessagesRecent(query.channelId, query.number),
this.handleMessagesConflict.bind(this),
`${this.name}#fetchMessagesRecent`,
);
this.fetchMessagesBeforeVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier(
@ -81,6 +87,7 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
async (query: PartialMessageListQuery) =>
await this.trusted.fetchMessagesBefore(query.channelId, query.messageOrderId as string, query.number),
this.handleMessagesConflict.bind(this),
`${this.name}#fetchMessagesBefore`,
);
this.fetchMessagesAfterVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier(
@ -89,13 +96,10 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
async (query: PartialMessageListQuery) =>
await this.trusted.fetchMessagesAfter(query.channelId, query.messageOrderId as string, query.number),
this.handleMessagesConflict.bind(this),
`${this.name}#fetchMessagesAfter`,
);
}
async ensureVerified(): Promise<void> {
/* do nothing */
}
async handleMetadataConflict(
changesType: AutoVerifierChangesType,
primaryMetadata: GuildMetadata | null,

View File

@ -59,8 +59,8 @@ export default class CombinedGuild
this.personalDBGuild = new PersonalDBGuild(personalDB, this.id, this.memberId);
this.socketGuild = new SocketGuild(socket, socketVerifier);
const diskSocket = new PairVerifierFetchable(this.personalDBGuild, this.socketGuild, 'Disk -> Socket');
const ramDiskSocket = new PairVerifierFetchable(this.ramGuild, diskSocket, 'RAM -> Disk');
const diskSocket = new PairVerifierFetchable(this.personalDBGuild, this.socketGuild, 'disk-socket');
const ramDiskSocket = new PairVerifierFetchable(this.ramGuild, diskSocket, 'ram-disk');
// TODO: I think this unverify is causing the RARE ALERTs
// do we need to unverify on connect? or just disconnect?

View File

@ -1,4 +1,4 @@
import { AsyncFetchable, AsyncLackable, Ensurable } from './guild-types';
import { AsyncFetchable, AsyncLackable } from './guild-types';
import {
Channel,
GuildMetadata,
@ -14,7 +14,7 @@ import PersonalDB from './personal-db';
import { AutoVerifierWithArg, PartialMessageListQuery } from './auto-verifier-with-args';
/** a guild connected to a local Sqlite database */
export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable, Ensurable {
export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
constructor(
private readonly db: PersonalDB,
private readonly guildId: number,
@ -59,10 +59,6 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable, E
return null; // personal db currently does not handle tokens
}
async ensureVerified(): Promise<void> {
/* do nothing, we are always ready */
}
// lacking Methods (resolving differences)
async handleMetadataChanged(changedMetaData: GuildMetadata): Promise<boolean> {

View File

@ -7,7 +7,7 @@ const LOG = Logger.create(__filename, electronConsole);
import * as socketio from 'socket.io-client';
import { Channel, GuildMetadata, Member, Message, Resource, Token } from './data-types';
import Globals from './globals';
import { Connectable, AsyncRequestable, AsyncGuaranteedFetchable, Ensurable } from './guild-types';
import { Connectable, AsyncRequestable, AsyncGuaranteedFetchable } from './guild-types';
import DedupAwaiter from './dedup-awaiter';
import Util from './util';
import SocketVerifier from './socket-verifier';
@ -17,7 +17,7 @@ import { EventEmitter } from 'tsee';
/** a guild connected to a socket.io socket server */
export default class SocketGuild
extends EventEmitter<Connectable>
implements AsyncGuaranteedFetchable, AsyncRequestable, Ensurable
implements AsyncGuaranteedFetchable, AsyncRequestable
{
private queryDedups = new Map<string, DedupAwaiter<unknown>>();
@ -89,10 +89,6 @@ export default class SocketGuild
this.socket.disconnect();
}
public async ensureVerified(): Promise<void> {
await this.verifier.ensureVerified();
}
// server helper functions
private async _query(timeout: number, endpoint: string, ...args: any[]): Promise<any> {

View File

@ -26,10 +26,6 @@ export interface AsyncFetchable {
}
export type Fetchable = SyncFetchable | AsyncFetchable;
export interface Ensurable {
ensureVerified: () => Promise<void>;
}
export interface AsyncGuaranteedFetchable {
fetchMetadata(): Promise<GuildMetadata>;
fetchMembers(): Promise<Member[]>;