Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix babel build error, convert Poll class into a function #1594

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 55 additions & 59 deletions src/utils/poll.ts
Original file line number Diff line number Diff line change
@@ -1,93 +1,89 @@
const DEFAULT_INTERVAL = 15000;
const DEFAULT_GRACE_RATIO = 0.33;

export class Poll {
private _cancelled = true;

// This flag is true when the poll is not running. You may
// use it in your code to determine if you should proceed.
public get cancelled(): boolean {
return this._cancelled;
}

private _counter = 0;
public get counter(): number {
return this._counter;
}

private graceInterval: number;
private pollInterval: NodeJS.Timer | null = null;
private lastCompleteTime = 0;
private blocked = false;
private isTabActive: boolean;
export interface Poll {
poll: (opts?: { forced?: boolean }) => void;
start: () => void;
stop: () => void;
destroy: () => void;
}

constructor(
private fn: (poll: Poll) => Promise<any>,
private interval: number,
graceRatio: number,
isTabActive: boolean,
) {
this.poll = this.poll.bind(this);
this.graceInterval = this.interval * graceRatio;
this.isTabActive = isTabActive;
}
const pollFactory = (
fn: () => Promise<any>,
interval: number,
graceRatio: number,
isTabActive: boolean,
) => {
let cancelled = true;
const graceInterval: number = interval * graceRatio;
let pollInterval: NodeJS.Timer | null = null;
let lastCompleteTime = 0;
let counter = 0;
let blocked = false;

public async poll(opts?: { forced?: boolean }) {
const poll = async (opts?: { forced?: boolean }) => {
// Only run poll if the previous call has finished and the poll
// is not cancelled
if (this.cancelled || this.blocked) {
if (cancelled || blocked) {
return;
}

const forced = opts && opts.forced;
// Return if we're invisible, unless it's first run
if (!forced && !this.isTabActive && this.lastCompleteTime !== 0) {
if (!forced && !isTabActive && lastCompleteTime !== 0) {
return;
}
if (!forced && Date.now() - this.lastCompleteTime < this.graceInterval) {
if (!forced && Date.now() - lastCompleteTime < graceInterval) {
return;
}
this.blocked = true;
blocked = true;

try {
await this.fn(this);
this.lastCompleteTime = Date.now();
await fn();
lastCompleteTime = Date.now();
} finally {
this._counter++;
this.blocked = false;
counter++;
blocked = false;
}
}
};

public start() {
const start = () => {
// Only start polling if it is currently stopped.
if (this.pollInterval != null) {
if (pollInterval != null) {
return;
}
this.lastCompleteTime = 0;
this._cancelled = false;
this.pollInterval = setInterval(this.poll, this.interval);
lastCompleteTime = 0;
cancelled = false;
pollInterval = setInterval(poll, interval);
// Also run a poll instantly, as we wanted to start it *now*,
// not X time in the future.
return this.poll();
}
return poll();
};

public stop() {
if (this.pollInterval) {
clearInterval(this.pollInterval);
const stop = () => {
if (pollInterval) {
clearInterval(pollInterval);
}
this._cancelled = true;
this.pollInterval = null;
}
cancelled = true;
pollInterval = null;
};

public destroy() {
this.stop();
this.fn = async () => undefined; // break possible cyclic reference
}
}
const destroy = () => {
stop();
fn = async () => undefined; // break possible cyclic reference
};

return {
poll,
start,
stop,
destroy,
};
};

export const createPoll = (
fn: (poll: Poll) => Promise<any>,
fn: () => Promise<any>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do use this in the UI to check whether the poll is cancelled.
Or maybe we only do that for useRequest 🤔 ?

interval: number = DEFAULT_INTERVAL,
isTabActive: boolean = true,
graceRatio: number = DEFAULT_GRACE_RATIO,
) => new Poll(fn, interval, graceRatio, isTabActive);
) => pollFactory(fn, interval, graceRatio, isTabActive);