Comparing version 1.0.1 to 1.0.2
@@ -6,2 +6,4 @@ class Task { | ||
this.type = null; | ||
this._workerId = null; | ||
this.created_at = Date.now(); | ||
} | ||
@@ -24,3 +26,5 @@ | ||
} | ||
setWorkerId(_workerId) { | ||
this._workerId = _workerId; | ||
} | ||
getId() { | ||
@@ -27,0 +31,0 @@ return this.id; |
@@ -21,4 +21,10 @@ const uuid = require('uuid'); | ||
this._maxTaskPerWorker = 10; | ||
this._pluggins = []; | ||
} | ||
addPluggin(pluggin) { | ||
this._pluggins.push(pluggin); | ||
pluggin.apply(this); | ||
} | ||
addWorkerAddress(address, workerType) { | ||
@@ -47,5 +53,7 @@ if (!this._workersAddress.has(workerType)) { | ||
this._tasks.set(taskId, task); | ||
task.setWorkerId(worker.getId()); | ||
worker.addTask(this._tasks.get(taskId)); | ||
this._workerTaskLookup.get(worker.getId()).push(task.getId()); | ||
this.emit('add', { worker }); | ||
this.emit('info', { type: 'task:new', task, worker }); | ||
debug(`New task added, previous task count ${this._tasks.size}`); | ||
@@ -76,5 +84,6 @@ return worker; | ||
for (let i = 0; i < this._maxWorkers; i++) { | ||
const worker = this._createWorker(Task.TYPE_FORK, workerAddressIndex); | ||
const worker = this._createWorker(taskType, workerAddressIndex); | ||
this._workerTaskLookup.set(worker.getId(), []); | ||
} | ||
this.emit('info', { type: 'workers:deployed' }); | ||
} | ||
@@ -117,6 +126,8 @@ _getFreeWorker(task, workerTaskLength = 0) { | ||
worker.create(); | ||
worker.on(this.handleWorkerMessage(worker)); | ||
worker.onChildMessage(this.handleChildMessage(worker)); | ||
// worker.onWorkerMessage(this.handleWorkerMessage(worker)); | ||
debug( | ||
`New Worker created, previous worker count ${this._workerTaskLookup.size}` | ||
); | ||
this.emit('info', { type: 'workers:created', worker }); | ||
return worker; | ||
@@ -127,2 +138,34 @@ } | ||
return data => { | ||
this.emit('info', { type: 'workers:message', worker, data }); | ||
switch (data.eventType) { | ||
case 'stop': | ||
this._workerTaskLookup.get(data.workerId).forEach(taskId => { | ||
this.handleTaskComplete({ taskId }, worker); | ||
this.emit('message', { | ||
...data, | ||
taskId, | ||
data: { message: 'Worker stopped suddenly.' }, | ||
}); | ||
}); | ||
const worker = this._createWorker(worker.getType()); | ||
this._workerTaskLookup.set(data.workerId, []); | ||
this.removeWorker(data.workerId); | ||
break; | ||
case 'exit': | ||
case 'crash': | ||
this._workerTaskLookup.get(data.workerId).forEach(taskId => { | ||
this.handleTaskComplete({ taskId }, worker); | ||
this.emit('message', { | ||
...data, | ||
taskId, | ||
data: { message: `Sudden ${data.eventType} of worker` }, | ||
}); | ||
}); | ||
break; | ||
} | ||
}; | ||
} | ||
handleChildMessage(worker) { | ||
return data => { | ||
this.emit('info', { type: 'child:message', worker, data }); | ||
switch (data.type) { | ||
@@ -140,2 +183,3 @@ case events.TASK_ERROR: | ||
handleTaskComplete(data, worker) { | ||
this.emit('info', { type: 'task:complete', data, worker }); | ||
return this.removeTask(data.taskId); | ||
@@ -164,2 +208,3 @@ } | ||
this._tasks.delete(taskId); | ||
this.emit('info', { type: 'task:deleted', taskId, workerId }); | ||
debug('A task deleted with id of %s', taskId); | ||
@@ -199,2 +244,3 @@ return true; | ||
this._workerTaskLookup.delete(workerId); | ||
this.emit('info', { type: 'workers:removed', worker }); | ||
debug('Worker with id %s has been deleted', worker.getId()); | ||
@@ -201,0 +247,0 @@ return worker.kill(); |
@@ -0,1 +1,2 @@ | ||
const respawn = require('respawn') | ||
const Task = require('./Task'); | ||
@@ -13,6 +14,20 @@ const path = require('path'); | ||
this._address = null; | ||
this.created_at = Date.now(); | ||
} | ||
on(handler) { | ||
this._worker.on('message', data => { | ||
getWorker() { | ||
return this._worker; | ||
} | ||
onWorkerMessage(handler) { | ||
['stop', 'exit', 'crash'].forEach((eventType) => { | ||
this._worker.on(eventType, (data) => handler({ | ||
eventType, | ||
workerId: this.getId(), | ||
...data, | ||
})) | ||
}); | ||
} | ||
onChildMessage(handler) { | ||
this._worker.child.on('message', data => { | ||
handler({ | ||
@@ -28,4 +43,15 @@ workerId: this.getId(), | ||
case Task.TYPE_FORK: | ||
this._worker = respawn([this._address], { | ||
name: this._id, // set monitor name | ||
env: process.env, // set env vars | ||
cwd: '.', // set cwd | ||
maxRestarts: 10, // how many restarts are allowed within 60s | ||
// or -1 for infinite restarts | ||
sleep: 1000, // time to sleep between restarts, | ||
kill: 30000, // wait 30s before force killing after stopping | ||
// stdio: [...], // forward stdio options | ||
fork: true // fork instead of spawn | ||
}); | ||
this._worker.start(); | ||
debug(`New worker created with id ${this._id}`); | ||
this._worker = fork(this._address); | ||
break; | ||
@@ -54,3 +80,3 @@ default: | ||
if (this._worker) { | ||
this._worker.send(payload); | ||
this._worker.child.send(payload); | ||
} | ||
@@ -69,3 +95,3 @@ } | ||
this._tasks.clear(); | ||
this._worker.kill(); | ||
this._worker.stop(); | ||
return true; | ||
@@ -72,0 +98,0 @@ } catch (e) { |
{ | ||
"name": "thekdar", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "", | ||
@@ -14,2 +14,3 @@ "main": "index.js", | ||
"debug": "^3.1.0", | ||
"respawn": "^2.5.0", | ||
"uuid": "^3.1.0" | ||
@@ -16,0 +17,0 @@ }, |
@@ -30,84 +30,3 @@ const Thekdar = require("../core/Thekdar"); | ||
}); | ||
it("should create three workers of fork type", () => { | ||
const thekdar = new Thekdar(); | ||
thekdar.addWorkerAddress(FORK_ADDRESS, Task.TYPE_FORK); | ||
const workers = []; | ||
for (let i = 0; i < 20; i++) { | ||
const task = {}; | ||
task.getType = jest.fn(() => Task.TYPE_FORK); | ||
task.setId = jest.fn(id => (task.id = id)); | ||
task.getId = jest.fn(() => task.id); | ||
let worker = thekdar.addTask(task); | ||
if (!workers.includes(worker.getId())) { | ||
workers.push(worker.getId()); | ||
} | ||
// Till 8 tasks in worker we will have 1 worker | ||
if (i === 8) { | ||
expect(thekdar._workers.get(Task.TYPE_FORK).size).toBe(1); | ||
} | ||
// After 9 tasks new worker will be created and workers will be 2 | ||
if (i === Thekdar.MAX_TASK_PER_WORKER - 1) { | ||
expect(thekdar._workers.get(Task.TYPE_FORK).size).toBe(2); | ||
expect(thekdar._workerTaskLookup.get(worker.getId()).length).toBe( | ||
Thekdar.MAX_TASK_PER_WORKER | ||
); | ||
} | ||
if (i === 19) { | ||
expect(thekdar._workers.get(Task.TYPE_FORK).size).toBe(3); | ||
expect(thekdar._workerTaskLookup.get(worker.getId()).length).toBe( | ||
Thekdar.MAX_TASK_PER_WORKER | ||
); | ||
} | ||
} | ||
expect(thekdar._workers.get(Task.TYPE_FORK).size).toBe(3); | ||
}); | ||
it("should only allow limited task per worker", () => { | ||
const thekdar = new Thekdar(); | ||
thekdar.addWorkerAddress(FORK_ADDRESS, Task.TYPE_FORK); | ||
for (let i = 0; i < 15; i++) { | ||
const task = {}; | ||
task.getType = jest.fn(() => Task.TYPE_FORK); | ||
task.setId = jest.fn(id => (task.id = id)); | ||
task.getId = jest.fn(() => task.id); | ||
thekdar.addTask(task); | ||
} | ||
thekdar._workerTaskLookup.forEach(tasks => { | ||
expect(tasks.length <= 10).toBe(true); | ||
}); | ||
}); | ||
it("should throw error if task not provided or type not provided", () => { | ||
const thekdar = new Thekdar(); | ||
thekdar.addWorkerAddress(FORK_ADDRESS, Task.TYPE_FORK); | ||
const task = {}; | ||
task.getType = jest.fn(); | ||
expect(() => thekdar.addTask()).toThrow(); | ||
expect(() => thekdar.addTask(task)).toThrow(); | ||
expect(task.getType).toBeCalled(); | ||
}); | ||
it("should return free worker", () => { | ||
const thekdar = new Thekdar(); | ||
thekdar.addWorkerAddress(FORK_ADDRESS, Task.TYPE_FORK); | ||
const task = new Task(); | ||
task.setType(Task.TYPE_FORK); | ||
task.setData({}); | ||
const worker = thekdar._getFreeWorker(task); | ||
expect(worker).toBeInstanceOf(Worker); | ||
expect(worker).not.toBe(null); | ||
expect(worker).toHaveProperty("_id"); | ||
}); | ||
it("should throw error when maximum workers created", () => { | ||
const thekdar = new Thekdar(); | ||
thekdar.addWorkerAddress(FORK_ADDRESS, Task.TYPE_FORK); | ||
for (let i = 0; i < 250; i++) { | ||
const task = {}; | ||
task.getType = jest.fn(() => Task.TYPE_FORK); | ||
task.setId = jest.fn(id => (task.id = id)); | ||
task.getId = jest.fn(() => task.id); | ||
if (i > 199) { | ||
expect(() => thekdar.addTask(task)).toThrow(); | ||
} else { | ||
thekdar.addTask(task); | ||
} | ||
} | ||
}); | ||
it("should remove worker", () => { | ||
@@ -114,0 +33,0 @@ const thekdar = new Thekdar(); |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
18172
3
532
2
+ Addedrespawn@^2.5.0
+ Addedps-tree@1.2.0(transitive)
+ Addedrespawn@2.6.0(transitive)
+ Addedxtend@4.0.2(transitive)