Pause suspended Reddit accounts
This commit is contained in:
1 parent
94049ed9c4
commit
7d039265e7
21 files changed
+368
-26
No files matched your search
@@ -38,6 +38,7 @@ import type { RecipientAccountStatusService } from './recipient-account-status.j
|
||||
import type { AccountEstablishmentService } from './account-establishment.js';
|
||||
import type { AccountGrowthService } from './account-growth.js';
|
||||
import type { AccountBrowsingSimulationService } from './account-browsing-simulation.js';
|
||||
import type { AccountSuspensionService } from './account-suspension.js';
|
||||
import type { ProcessedPost, ProcessResult } from './processor.js';
|
||||
import type { ConversationEventRepository } from '../database/conversation-event-repository.js';
|
||||
import type { ConversationLearningRepository } from '../database/conversation-learning-repository.js';
|
||||
@@ -91,6 +92,8 @@ export interface RedditAccountRuntimeResources {
|
||||
mediaSyncService: MediaSyncService;
|
||||
recipientAccountStatusService: RecipientAccountStatusService;
|
||||
establishmentService: AccountEstablishmentService;
|
||||
/** Present in concrete runtimes; optional for narrow lifecycle test fixtures. */
|
||||
suspensionService?: AccountSuspensionService;
|
||||
/**
|
||||
* Comment-based account growth. Optional because a runtime is fully
|
||||
* functional without it, and it is disabled per account by default.
|
||||
@@ -107,6 +110,8 @@ export interface RedditAccountRuntimeLifecycle {
|
||||
start(): void | Promise<void>;
|
||||
/** Stop and await this account's schedules/loop, then close its browser. */
|
||||
stop(): void | Promise<void>;
|
||||
/** Immediately halt account work after a definitive suspension signal. */
|
||||
pause?(reason: string): void;
|
||||
/** Process a post assigned by the shared discovery scheduler. */
|
||||
dispatchPost?(post: RedditPost, signal?: AbortSignal): Promise<void>;
|
||||
preparePost?(post: RedditPost, signal?: AbortSignal): Promise<ProcessResult>;
|
||||
@@ -123,6 +128,7 @@ export type RedditAccountRuntimeState =
|
||||
| 'starting'
|
||||
| 'running'
|
||||
| 'stopping'
|
||||
| 'paused'
|
||||
| 'stopped'
|
||||
| 'failed';
|
||||
|
||||
@@ -197,6 +203,17 @@ export class RedditAccountRuntime {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspension can be discovered by work that this runtime is currently
|
||||
* awaiting. Keep this synchronous so it cannot wait on its own loop.
|
||||
*/
|
||||
pause(reason: string): void {
|
||||
if (this.state === 'stopped' || this.state === 'failed') return;
|
||||
this.failure = reason;
|
||||
this.state = 'paused';
|
||||
this.lifecycle.pause?.(reason);
|
||||
}
|
||||
|
||||
snapshot(): RedditAccountRuntimeSnapshot {
|
||||
return {
|
||||
accountId: this.session.accountId,
|
||||
@@ -294,7 +311,9 @@ export class RedditAccountRuntimeManager {
|
||||
|
||||
async startEnabled(): Promise<RedditAccountRuntimeManagerSnapshot> {
|
||||
const enabled = this.accounts.listPublic().filter(isEnabledAccount);
|
||||
await Promise.all(enabled.map((account) => this.start(account.accountId)));
|
||||
// A broken or suspended session belongs to one account. Do not prevent
|
||||
// other verified accounts from starting because of it.
|
||||
await Promise.allSettled(enabled.map((account) => this.start(account.accountId)));
|
||||
return this.snapshot();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user