<commit_before>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { PromiseDelegate } from '@phosphor/coreutils';

import { IDisposable } from '@phosphor/disposable';

import { ISignal, Signal } from '@phosphor/signaling';

/**
 * A class that wraps an asynchronous function to poll at a regular interval
 * with exponential increases to the interval length if the poll fails.
 *
 * #### Notes
 * The generic argument `T` indicates the resolved type of the promises returned
 * by the poll's promise factory.
 */
export class Poll<T = any> implements IDisposable {
  /**
   * Instantiate a new poll with exponential back-off in case of failure.
   *
   * @param options - The poll instantiation options.
   */
  constructor(options: Poll.IOptions<T>) {
    const { factory, interval, max, min, name, variance, when } = options;

    if (interval > max) {
      throw new Error('Poll interval cannot exceed max interval length');
    }
    if (min > max || min > interval) {
      throw new Error('Poll min cannot exceed poll interval or poll max');
    }

    this.interval =
      typeof interval === 'number' ? Math.round(Math.abs(interval)) : 1000;
    this.max = typeof max === 'number' ? Math.abs(max) : 10 * this.interval;
    this.min = typeof min === 'number' ? Math.abs(min) : 100;
    this.name = name || 'unknown';
    this.variance = typeof variance === 'number' ? variance : 0.2;
    this._factory = factory;

    // Cache the original interval length and start polling.
    this._ready = (when || Promise.resolve())
      .then(() => {
        this._connected = true;
        this._isReady = true;
        this._ready = null;
        return this._schedule(interval);
      })
      .catch(() => {
        this._isReady = true;
        this._ready = null;
        return this._schedule(interval);
      });
  }

  /**
   * The polling interval.
   */
  readonly interval: number;

  /**
   * The maximum interval between poll requests.
   */
  readonly max: number;

  /**
   * The minimum interval between poll requests.
   */
  readonly min: number;

  /**
   * The name of the poll. Defaults to `'unknown'`.
   */
  readonly name: string;

  /**
   * The range within which the poll interval jitters.
   */
  readonly variance: number;

  /**
   * A signal emitted when the poll is disposed.
   */
  get disposed(): ISignal<this, void> {
    return this._disposed;
  }

  /**
   * Whether the poll is disposed.
   */
  get isDisposed(): boolean {
    return this._isDisposed;
  }

  /**
   * A handle to the next link in the poll promise chain.
   */
  get next(): Poll.Next {
    if (this._isReady) {
      return this._outstanding || this._schedule(this.interval);
    }
    const ready = this._ready;
    const delegate = new PromiseDelegate<Poll.Next>();

    ready.then(next => {
      delegate.resolve(next);
    });

    return delegate;
  }

  /**
   * A signal emitted when the poll promise rejects.
   */
  get rejected(): ISignal<this, any> {
    return this._rejected;
  }

  /**<commit_msg>Better document Poll#next.<commit_after>// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { PromiseDelegate } from '@phosphor/coreutils';

import { IDisposable } from '@phosphor/disposable';

import { ISignal, Signal } from '@phosphor/signaling';

/**
 * A class that wraps an asynchronous function to poll at a regular interval
 * with exponential increases to the interval length if the poll fails.
 *
 * #### Notes
 * The generic argument `T` indicates the resolved type of the promises returned
 * by the poll's promise factory.
 */
export class Poll<T = any> implements IDisposable {
  /**
   * Instantiate a new poll with exponential back-off in case of failure.
   *
   * @param options - The poll instantiation options.
   */
  constructor(options: Poll.IOptions<T>) {
    const { factory, interval, max, min, name, variance, when } = options;

    if (interval > max) {
      throw new Error('Poll interval cannot exceed max interval length');
    }
    if (min > max || min > interval) {
      throw new Error('Poll min cannot exceed poll interval or poll max');
    }

    this.interval =
      typeof interval === 'number' ? Math.round(Math.abs(interval)) : 1000;
    this.max = typeof max === 'number' ? Math.abs(max) : 10 * this.interval;
    this.min = typeof min === 'number' ? Math.abs(min) : 100;
    this.name = name || 'unknown';
    this.variance = typeof variance === 'number' ? variance : 0.2;
    this._factory = factory;

    // Cache the original interval length and start polling.
    this._ready = (when || Promise.resolve())
      .then(() => {
        this._connected = true;
        this._isReady = true;
        this._ready = null;
        return this._schedule(interval);
      })
      .catch(() => {
        this._isReady = true;
        this._ready = null;
        return this._schedule(interval);
      });
  }

  /**
   * The polling interval.
   */
  readonly interval: number;

  /**
   * The maximum interval between poll requests.
   */
  readonly max: number;

  /**
   * The minimum interval between poll requests.
   */
  readonly min: number;

  /**
   * The name of the poll. Defaults to `'unknown'`.
   */
  readonly name: string;

  /**
   * The range within which the poll interval jitters.
   */
  readonly variance: number;

  /**
   * A signal emitted when the poll is disposed.
   */
  get disposed(): ISignal<this, void> {
    return this._disposed;
  }

  /**
   * Whether the poll is disposed.
   */
  get isDisposed(): boolean {
    return this._isDisposed;
  }

  /**
   * A handle to the next link in the poll promise chain.
   */
  get next(): Poll.Next {
    // If polling has begun return the outstanding promise or schedule one.
    if (this._isReady) {
      return this._outstanding || this._schedule(this.interval);
    }

    // Return a proxy to the ready promise.
    const ready = this._ready;
    const proxy = new PromiseDelegate<Poll.Next>();

    ready.then(next => {
      proxy.resolve(next);
    });

    return proxy;
  }

  /**
   * A signal emitted when the poll promise rejects.
   */
  get rejected(): ISignal<this, any> {
    return this._rejected;
  }

  /**
{'fraction_non_alphanumeric': 0.12223460130510902, 'fraction_numerical': 0.003501512016552602, 'mean_word_length': 2.613571017826337, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2621805', 'n_tokens_mistral': 1884, 'n_tokens_neox': 1784, 'n_words': 630}