-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
189 lines (154 loc) · 5.19 KB
/
Copy pathindex.js
File metadata and controls
189 lines (154 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
*
*
*
*/
'use strict';
var uuid = require('uuid/v1'),
cp = require('child_process'),
numCPUs = require('os').cpus().length,
cpu_limit = 2
//TODO: Test how many cpus we can max out before we get memory warnings on heroku, test difference between free and paid version
var queue = (function () {
var module = {},
db, children = [], childState = [], rootDir = null, childStates = [], childJobs = []
/**
* Initiate the queue module, by providing an sqlite instance, afterwards a job table is initialised, which will hande the jobs
*
* @param {Object} `postgres` postgres db object
*/
module.init = function ( postgres, dir, callback ) {
rootDir = dir
db = postgres
//Create job table if not already exists
db.query("CREATE TABLE IF NOT EXISTS svift_queue (id SERIAL PRIMARY KEY, job_id text, status integer, added TIMESTAMP, start_time TIMESTAMP, end_time TIMESTAMP, params text)", function (err, result){
if(err){
//This creates an error if the svift_queue table is created for the first time, no worries about that...
console.log(err)
}
//TODO: DELETE * FROM svift_queue
db.query("UPDATE svift_queue SET status = 0 WHERE status = 1", function (err, result){
if(err){
console.log(err)
}
console.log('CPUs:', ((numCPUs>cpu_limit)?cpu_limit:numCPUs))
for(let i = 0; i<cpu_limit && i<numCPUs; i++){
children.push(cp.fork(__dirname + '/child'))
childState.push(-1)
childStates.push({})
childJobs.push(-1)
children[i].send({func:'init', params:{id:i, dir:rootDir}})
children[i].on('message', function(m) {
module[m.func](m.params)
})
}
callback()
})
})
}
module.initDone = function ( params ) {
childState[params.child_id] = 0
module.next()
}
/**
* Check in the queue table if there is a job todo, then run it, otherwise wait for jobs
*/
module.next = function () {
db.query("SELECT job_id, params FROM svift_queue WHERE status = 0 ORDER BY start_time ASC", function(err, result) {
let rows = result.rows
if(err){
console.log(err)
}else if ( rows && rows.length >= 1 ) {
var ri = 0
children.some( function (child, ci) {
if(childState[ci] === 0){
childState[ci] = 1
childJobs[ci] = rows[ri].job_id
//TODO: this object should be automatically generated through the available render methods??
//Video is being removed temporarily: ++{mpeg:0}
childStates[ci] = {svg:0,html:0,png:0,gif:0,social:0,aws:0,zip:0}
db.query("UPDATE svift_queue SET status = 1, start_time = NOW() WHERE job_id = $1", [rows[ri].job_id], function (err) {
if (err) {
console.log(err.message)
}
})
child.send({func:'start',params:{id:rows[ri].job_id, params:JSON.parse(rows[ri].params)}})
ri++
if(ri >= rows.length){
return true
}
}
})
}
})
}
/**
* Check in the queue table if there is a job todo, then run it, otherwise wait for jobs
*/
module.addJob = function (job_params, callback) {
db.query("INSERT INTO svift_queue (job_id, status, added, params) VALUES ($1,$2, NOW() ,$3) RETURNING id", [uuid(), 0, JSON.stringify(job_params)], function (err, result) {
if (err) {
console.log(err.message)
}
let lastID = result.rows[0].id
db.query("SELECT job_id FROM svift_queue WHERE id = $1", [lastID], function(err, result){
if(err){
console.log(err.message)
}
callback(result.rows[0].job_id)
module.next()
})
})
}
module.jobUpdate = function (params) {
module.updateStat(params.child_id, params.type, params.state)
}
module.jobDone = function (params) {
db.query("UPDATE svift_queue SET status = 2, end_time = NOW() WHERE job_id = $1", [params.job_id], function (err) {
if (err) {
console.log(err.message)
}
childState[params.child_id] = 0
module.next()
})
}
module.jobStat = function (job_id, callback){
db.query("SELECT status FROM svift_queue WHERE job_id = $1", [job_id], function(err, result){
let rows = result.rows
if(rows.length<1){
callback('job_id not found', null)
}else{
var r = {status:rows[0].status}
if(rows[0].status == 1){
childJobs.forEach(function(j, ji){
if(j == job_id){
r['full'] = childStates[ji]
}
})
}
callback(null, r)
}
})
}
module.updateStat = function(child_id, type, state){
if(!(type in childStates[child_id])){
childStates[child_id][type] = 0
}
childStates[child_id][type] = state
}
module.stats = function ( callback ) {
db.query("SELECT status, COUNT(*) FROM svift_queue GROUP BY status", function(err, result) {
if (err) {
console.log(err.message)
}
callback(result.rows)
})
}
module.exit = function () {
children.forEach(function(child){
child.kill('SIGINT')
})
}
return module;
})();
module.exports = queue;