Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
threadedclass
Advanced tools
[![CircleCI](https://circleci.com/gh/nytamin/threadedClass.svg?style=svg)](https://circleci.com/gh/nytamin/threadedClass) [![codecov](https://codecov.io/gh/nytamin/threadedClass/branch/master/graph/badge.svg)](https://codecov.io/gh/nytamin/threadedClass)
Fork instances of classes (while keeping typings) with one line of code.
npm install threadedclass
Let's say you have a class that has several computational-heavy methods:
// Normal, single-threaded way:
import { Professor } from './professor'
function getStory() {
let mrSmith = new Professor('maths', 'greek')
let story = mrSmith.talkAboutAncientGreece() // takes a loong time
return story
}
Threaded-class
helps you create an asynchronous version of the instance of that class.
The instance will have almost the same typings-API as the original (all methods return promises instead), but will run in a separate thread.
// Multi-threaded, asynchronous way:
import { threadedClass} from 'threadedclass'
import { Professor } from './professor'
async function getStory() {
let mrSmith = await threadedClass<Professor>('./professor.js', 'Professor', ['maths', 'greek'])
let story = await mrSmith.talkAboutAncientGreece() // still takes a loong time, but now runs in a separate thread
return story
}
The instance returned by threadedClass()
has methods equivalent to the original, but all properties and methods will be asynchronous (return Promises).
import { threadedClass} from 'threadedclass'
import { Professor } from './professor'
threadedClass<Professor>(
'./professor.js', // Path to imported module (this should be the same path as is in require('XX') or import {class} from 'XX'} )
'Professor' , // The export name for the class to be forked
['maths', 'greek'], // Array of arguments to be fed into the class constructor
{} // Config (see below)
)
.then((instance) => {
return mrSmith.talkAboutAncientGreece() // All methods returns a Promise
})
.then((story) => {
console.log(story)
})
var threadedClass = require('threadedclass').threadedClass
var Professor = require('./professor')
threadedClass('./professor.js', Professor, ['maths', 'greek'])
.then((instance) => {
return mrSmith.talkAboutAncientGreece() // All methods returns a Promise
})
.then((story) => {
console.log(story)
})
<script type="text/javascript" src="lib/threadedClass.js"></script>
<script type="text/javascript" src="professor.js"></script>
<script type="text/javascript">
var threadedClass = ThreadedClass.threadedClass
threadedClass('../professor.js', Professor, ['maths', 'greek'], { // path to module is relative to threadedClass.js
pathToWorker: 'lib/threadedclass-worker.js' // in browser, a path to the worker-scrip must also be provided
})
.then((instance) => {
return mrSmith.talkAboutAncientGreece() // All methods returns a Promise
})
.then((story) => {
console.log(story)
})
</script>
An optional options object can be passed to threadedClass() with the following properties:
Option | Type | Description |
---|---|---|
threadUsage | number | A number between 0 - 1, how large part of a thread the instance takes up. For example; if set to 0.1, a thread will be re-used for up to 10 instances. |
threadId | string | Set to an arbitrary id to put the instance in a specific thread. Instances with the same threadIds will be put in the same thread. |
autoRestart | boolean | If the process crashes or freezes it's automatically restarted. (ThreadedClassManager will emit the "restarted" event upon restart) |
disableMultithreading | boolean | Set to true to disable multi-threading, this might be useful when you want to disable multi-threading but keep the interface unchanged. |
pathToWorker | string | Set path to worker, used in browser |
freezeLimit | number | (milliseconds), how long to wait before considering the child to be unresponsive. (default is 1000 ms) |
import { MyClass } from './myModule'
import { DatClass } from 'dat-library'
import { StringDecoder } from 'string_decoder'
When calling a method of your threaded instance (threaded.myMethod()
), there are some limitations to what data-types are allowed to be provided and returned.
threaded.myMethod(() => {})
) a reference to the method will be stored indefinitely, because we cannot determine if the reference is valid in the child process.threadUsage: 0.1
will put 10 instances in a thread before spawning a new).Different API:s will be used for threading, depending on the platform:
Platform | API used |
---|---|
Browser | Web-workers |
NodeJS <10.x | Child process |
NodeJS 10.x - 11.7 | Worker-threads (if node --experimental-worker flag is enabled) |
NodeJS >11.8 | Worker-threads |
Doing method-calls to threads is slower than when running in a single thread. The greatest benefit comes when there is heavy computations to be made.
This table shows measured round-trip times of just calling a method:
Platform | API used | Avg. time per call |
---|---|---|
NodeJS 8.9.x | Single-thread mode | 0.000200 ms per call |
NodeJS 8.9.x | Child process | 0.117000 ms per call |
NodeJS 10.15.x | Single-thread mode | 0.000080 ms per call |
NodeJS 10.15.x | Child process | 0.090000 ms per call |
NodeJS 10.15.x | Worker-threads | 0.045000 ms per call |
NodeJS 11.14.x | Single-thread mode | 0.000085 ms per call |
NodeJS 11.14.x | Worker-threads | 0.047000 ms per call |
Browser (Chrome) | Single-thread mode | 0.001500 ms per call |
Browser (Chrome) | Web-workers | 0.140000 ms per call |
FAQs
[![Lint and Test](https://github.com/nytamin/threadedClass/actions/workflows/lint-and-test.yml/badge.svg)](https://github.com/nytamin/threadedClass/actions/workflows/lint-and-test.yml) [![codecov](https://codecov.io/gh/nytamin/threadedClass/branch/master/
We found that threadedclass demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers 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.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.