
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
sequentially-delayed-tasks
Advanced tools
A tool used to run several tasks (function) in sequence with retry logic and allows us to set delays before the next task will trigger
This utility allows you to perform a series of tasks (functions) that will run the next task after the next one completes (or if it fails... more on handling these below). A group of "tasks" is called a "job" which we use to organize them. Note that this including most of my projects are written in TypeScript. The Job manager allows for multiple jobs to be run in parallel as well.
Why did I make it and where did I use this? well there are several encounters I had wherein certain "stuffs" will require some delays before you call the next one. an example of these includes API calls where they use rate limitters and will block your IP or machine from creating calls temporarilly (or permanently) if you seem to spam the service even if its a valid request. Another use case is where you need something like a cron-like task that runs over a certain period of time until all tasks are completed.
First install the tool using the following
npm i sequentially-delayed-tasks --save
in your TS file, write the following
import TaskManager from 'sequentially-delayed-tasks';
const tasks = new TaskManager();
tasks.addJob({
name: 'test1',
tasks: [
{
function: async (): Promise<boolean> => {
console.log('Task 1 started in 0 secondth');
return true;
},
},
{
delay: 2000,
data: {
val1: 'Hello',
val2: 'World',
},
function: async (data): Promise<boolean> => {
console.log('Task 2 started after 2 seconds');
console.log(`The data says: ${data.val1} data.val2}`);
return true;
},
},
{
delay: 1000,
function: async (): Promise<boolean> => {
ingredients.push('oil');
console.log('Task 3 started after 3 seconds');
return true;
},
behavior: {
doNotBreakOnError: true,
maxReties: 5,
}
},
],
});
await tasks.execJob('test1');
Lets try and understand what just happened there. First we created a new instance of TaskManager. It can be constructed using the default with no parameter which we just did. This means it will use the default behaviors to handle tasks. If you need to customize these behaviors however, you will need to provide the configuration in the parameter as such...
const tasks = new TaskManager({
doNotBreakOnError: true,
maxReties: 2,
skipItemOnFail: true,
});
How these 3 behaviors tie up is explained below
The next thing we did is add a new Job entry. A job entry consists of a name (which is the unique key identifier) and an array of "Task Configurations". These configurations require a function only as a requirement. this is the very function that will be triggered when the Job execution has activated it. It also has other optional properties that you can set to change how the task is handled
If you need to handle certain things during each events triggering in the TaskManager, subscribe to its EventEmitter. The names are already self explanatory and their key constants can be found in the Events enumeration object.
import TaskManager, { Events } from './TaskManager';
function onJobStarted(name: string): void {
console.log(`Job "${name}" has started.`);
}
function onJobCompleted(name: string): void {
console.log(`Job "${name}" has completed.`);
}
function onJobFailed(name: string, err: Error): void {
console.error(`Job "${name}" has failed with error ${err.message}.`);
}
function onjobTerminated(name: string, taskNumber: number): void {
console.log(`Job "${name}" on task # ${taskNumber} was terminated.`);
}
function onTaskStarted(name: string, taskNumber: number): void {
console.log(`Job "${name}" on task # ${taskNumber} has started.`);
}
function onTaskCompleted(name: string, taskNumber: number): void {
console.log(`Job "${name}" on task # ${taskNumber} has completed.`);
}
function onTaskSkipping(name: string, taskNumber: number): void {
console.error(`Job "${name}" on task # ${taskNumber} skipped.`);
}
function onTaskRetrying(name: string, taskNumber: number, attempts: number): void {
console.error(`Job "${name}" on task # ${taskNumber} retry #${attempts}.`);
}
function onTaskFailed(name: string, taskNumber: number, err: Error): void {
console.error(`Job "${name}" on task # ${taskNumber} has failed with error "${err.message}".`);
}
const tasks = new TaskManager();
tasks.on(Events.JobStarted, onJobStarted);
tasks.on(Events.JobCompleted, onJobCompleted);
tasks.on(Events.JobFailed, onJobFailed);
tasks.on(Events.JobTerminated, onjobTerminated);
tasks.on(Events.TaskStarted, onTaskStarted);
tasks.on(Events.TaskCompleted, onTaskCompleted);
tasks.on(Events.TaskFailed, onTaskFailed);
tasks.on(Events.TaskRetrying, onTaskRetrying);
tasks.on(Events.TaskSkipping, onTaskSkipping);
FAQs
A tool used to run several tasks (function) in sequence with retry logic and allows us to set delays before the next task will trigger
We found that sequentially-delayed-tasks demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.