Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

@jayarjo/scheduler

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jayarjo/scheduler - npm Package Compare versions

Comparing version
1.1.0
to
1.1.1
+7
lib/index.d.ts
import { Scheduler } from "./Scheduler";
import { SchedulerStats } from "./SchedulerStats";
export * from './Task';
export * from './Scheduler';
export * from './SchedulerStats';
export declare const scheduler: Scheduler;
export declare const schedulerStats: SchedulerStats;
import { Task, TaskSchema } from './';
export declare class Poller {
private ratePerMin;
polls: Map<string, Task>;
floodingPolls: Map<string, boolean>;
get isStarted(): boolean;
get spareRate(): number;
get spareInterval(): number;
get intervalForFloodingPoll(): number;
get unscheduledPolls(): Task[];
constructor(ratePerMin?: number);
addPoll(schema: TaskSchema): any;
addPolls(schemas: TaskSchema[]): any[];
removePoll(poll: Task, reallocateFloodIntervals?: boolean): any;
removePoll(uid: string, reallocateFloodIntervals?: boolean): any;
isFlooding(uid: string): boolean;
isFlooding(poll: Task): boolean;
isScheduled(uid: string): boolean;
isScheduled(poll: Task): boolean;
ratePerMinFor(interval: any): number;
setIntervalInFloodingPolls(interval: any): void;
start(): any[];
stop(): void;
restart(): void;
reset(): void;
destroy(): void;
}
import { Task, scheduler, TimeUnits } from './';
export class Poller {
constructor(ratePerMin = 2000) {
this.ratePerMin = ratePerMin;
this.polls = new Map();
// registry of polls that do not have specific interval and have to accomodate
// to remaining quota
this.floodingPolls = new Map();
}
get isStarted() {
return !!(this.polls.size && this.polls.size > this.unscheduledPolls.length);
}
get spareRate() {
let spareRate = this.ratePerMin;
this.polls.forEach((poll) => {
if (!this.isFlooding(poll)) {
spareRate -= this.ratePerMinFor(poll.interval);
}
});
return spareRate;
}
get spareInterval() {
const spareRate = this.spareRate;
return Math[spareRate < 0 ? 'ceil' : 'floor'](TimeUnits.MINUTE / spareRate);
}
get intervalForFloodingPoll() {
// NOTE: observables might have made it cleaner here
const spareInterval = this.spareInterval;
return spareInterval < 0 || !this.floodingPolls.size
? spareInterval
: Math.floor(spareInterval * this.floodingPolls.size);
}
get unscheduledPolls() {
const unscheduledPolls = [];
this.polls.forEach((poll) => {
if (!this.isScheduled(poll)) {
unscheduledPolls.push(poll);
}
});
return unscheduledPolls;
}
addPoll(schema) {
return this.addPolls([schema])[0];
}
addPolls(schemas) {
schemas.forEach((schema) => {
const poll = new Task(schema);
this.polls.set(poll.uid, poll);
if (!schema.interval) {
this.floodingPolls.set(poll.uid, true);
}
});
return this.start();
}
removePoll(arg, reallocateFloodIntervals = true) {
const poll = arg instanceof Task ? arg : this.polls.get(arg);
if (poll) {
this.floodingPolls.delete(poll.uid);
this.polls.delete(poll.uid);
if (reallocateFloodIntervals) {
this.setIntervalInFloodingPolls(this.intervalForFloodingPoll);
}
}
}
isFlooding(arg) {
return this.floodingPolls.has(arg instanceof Task ? arg.uid : arg);
}
isScheduled(arg) {
return !!scheduler.getTask(arg instanceof Task ? arg.uid : arg);
}
ratePerMinFor(interval) {
return interval < 0 ? 0 : TimeUnits.MINUTE / interval;
}
setIntervalInFloodingPolls(interval) {
this.floodingPolls.forEach((_, uid) => {
this.polls.get(uid).interval = interval;
});
}
start() {
const pollsToAdd = this.unscheduledPolls;
if (pollsToAdd.length) {
const interval = this.intervalForFloodingPoll;
// it is meant that dev will test if there's a time slot for a given poll prior to trying to add it, if dev
// ignores this prerequisite, then we abort everything and throw an exception directly into his face
if (interval < 0) {
// unregister polls
pollsToAdd.forEach((poll) => {
this.removePoll(poll, false);
});
throw new Error(`poller quota of ${this.ratePerMin}/min exceeded by ${this.ratePerMinFor(Math.abs(interval))}/min`);
}
else {
const pollIds = [];
this.setIntervalInFloodingPolls(interval);
// submit new polls as tasks to scheduler
pollsToAdd.forEach((poll) => {
pollIds.push(scheduler.addTask(poll));
});
return pollIds;
}
}
}
stop() {
this.polls.forEach((poll) => {
scheduler.removeTask(poll.uid);
poll.runAt(0); // at of 0 will be set automatically when task is re-added
});
}
restart() {
this.stop();
this.start();
}
reset() {
this.stop();
this.polls.clear();
this.floodingPolls.clear();
}
// deprecated
destroy() {
this.reset();
}
}
/// <reference types="node" />
import EventEmitter from 'events';
import { Task, TaskSchema, TimeUnits } from './Task';
export declare class Scheduler extends EventEmitter {
private randomStart;
tasks: Map<string, Task>;
private timer;
constructor(randomStart?: boolean);
run(): void;
addTask(task: Task): string;
addTask(schema: TaskSchema): string;
addTask(fn: Function): string;
getTask(uid: string): Task;
runIn(fn: Function, amount: number, unit?: TimeUnits, repeatTimesBeforeFail?: number): Promise<any>;
runOnceIn(fn: Function, amount: number, unit?: TimeUnits): Promise<any>;
runEvery(fn: Function, interval: number, unit?: TimeUnits, repeatTimesBeforeFail?: any): string;
removeTask(uid: string): void;
removeTask(task: Task): void;
clear(): void;
destroy(): void;
private runIfDue;
private runTask;
}
import { Scheduler } from './Scheduler';
export declare class SchedulerStats {
idle: number;
running: number;
completed: number;
successfulRuns: number;
failedRuns: number;
get total(): number;
get totalRuns(): number;
constructor(s: Scheduler);
reset(): void;
}
export declare enum TaskState {
IDLE = "idle",
RUNNING = "running",
SUCCEEDED = "succeeded",
FAILED = "failed"
}
export declare enum TimeUnits {
MILLISECOND = 1,
SECOND = 1000,
MINUTE = 60000,
HOUR = 3600000,
DAY = 86400000,
MONTH = 2592000000,
YEAR = 31536000000
}
export declare type TaskSchema = {
fn: Function;
args?: any[];
at?: number;
interval?: number;
repeatTimesBeforeFail?: number;
onSuccess?: (result: any, task: Task) => void;
onFailure?: (error: Error, task: Task) => void;
};
export declare class Task {
private schema;
private fails;
private _uid;
get uid(): string;
get at(): number;
set at(value: number);
get interval(): number;
set interval(value: number);
private _state;
get state(): TaskState;
get isIdle(): boolean;
get isComplete(): boolean;
get isDue(): boolean;
get isOneTime(): boolean;
constructor(fn: Function);
constructor(_schema: TaskSchema);
/**
* To differentiate between successful or failed run, fn should return a Promise.
* Otherwise every run will be considered successful.
*/
run(): Promise<any>;
repeatEvery(interval: number, unit?: TimeUnits): Task;
runAt(time: number): Task;
runAt(date: Date): Task;
toString(): string;
}
export declare const isIterable: (obj: any) => boolean;
export declare const isIterableIterator: (obj: any) => boolean;
export declare const guid: (prefix?: string) => string;
export declare const isPromise: (obj: any) => boolean;
export declare const random: (min: any, max: any) => any;
+4
-4

@@ -30,3 +30,3 @@ import { guid, isPromise } from './Utils';

onSuccess: () => { },
onFailure: () => { }
onFailure: () => { },
};

@@ -70,8 +70,8 @@ this.schema = Object.assign({}, defaults, typeof arg === 'function' ? { fn: arg } : arg);

run() {
const { fn, args = [], onSuccess, onFailure, repeatTimesBeforeFail } = this.schema;
const { fn, args = [], onSuccess, onFailure, repeatTimesBeforeFail, } = this.schema;
if (this._state !== TaskState.IDLE) {
return Promise.reject(new Error(`task ${this.uid} is either already ${this.state}!`));
}
const handleCompletion = isOk => {
return result => {
const handleCompletion = (isOk) => {
return (result) => {
if (isOk) {

@@ -78,0 +78,0 @@ if (this.isOneTime) {

@@ -13,7 +13,2 @@ export const isIterable = obj => obj && typeof obj[Symbol.iterator] === 'function';

})();
export const invariant = (expr, errMsg) => {
if (expr) {
throw new Error(errMsg);
}
};
export const isPromise = obj => obj && typeof obj.then === 'function';

@@ -20,0 +15,0 @@ export const random = (min, max) => {

{
"name": "@jayarjo/scheduler",
"version": "1.1.0",
"version": "1.1.1",
"description": "Schedule a task to execute after some period, regularly with a given interval, just given amount of times, or simply until it succeeds.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [

@@ -7,0 +8,0 @@ "lib/"