-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver
More file actions
executable file
·244 lines (209 loc) · 7.14 KB
/
server
File metadata and controls
executable file
·244 lines (209 loc) · 7.14 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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/usr/bin/env coffee
# Server for manage genetic algorithm clients
# Include third libraries
async = require 'async'
bodyParser = require 'body-parser'
commander = require 'commander'
express = require 'express'
mongo = require 'mongodb'
progress = require 'progress'
request = require 'request'
# Include own libraries
Server = require './lib/Server'
Timer = require './lib/timer'
actualGeneration = 0
aQueue = null
aServer = null
argv =
urlMongo: 'mongodb://localhost:27017/reuse'
httpPort: 8000
projectName: null
urlSync: 'http://localhost:8081'
sync: false
deliverTimer = new Timer
generalTimer = new Timer
httpServer = express()
initialTime = null
MongoClient = mongo.MongoClient
PARALELL_TASKS = 1
progressBar = null
requestTimer = new Timer
syncAuth = false
taskFinishedCounter = 0
workTimer = new Timer
# Report will print end of execution
printReport = ->
generalTimer.stop()
console.info ''
console.info '=== REPORT ==='
console.info 'Initial Time : ' + generalTimer.getInitialDate()
console.info 'End Time : ' + generalTimer.getEndDate()
console.info 'Total Duration : ' + generalTimer.getTime()
console.info ''
console.info 'Time work in server : ' + workTimer.getTime()
console.info 'Request time : ' + requestTimer.getTime()
console.info 'Deliver time : ' + deliverTimer.getTime()
console.info ''
console.info 'Total tasks completed: ' + taskFinishedCounter
return
sendTakeToSyncServer = (task, callback) ->
# Ask sync server for continue or wait
requestSyncTakeOptions =
url: argv.urlSync
form:
action : 'take'
generation: aServer.getGeneration()
project : argv.projectName
request.post requestSyncTakeOptions, (error, response, body) ->
console.error error if error
if body is 'true'
syncAuth = true
processData task, callback
else
syncAuth = false
task.response.end JSON.stringify sleep: true
callback()
sendLeaveToSyncServer = (callback) ->
if argv.sync and syncAuth
requestSyncLeaveOptions =
form:
action : 'leave'
project: argv.projectName
url: argv.urlSync
request.post requestSyncLeaveOptions, (error, response, body) ->
console.error error if error
if body is 'true'
syncAuth = false
callback()
endCommunication = (task, answer, callback) ->
task.response.end JSON.stringify answer
if answer.action is 'deliver' and syncAuth
sendLeaveToSyncServer callback
else
callback()
processData = (task, callback) ->
deliverTimer.start()
requestTimer.start()
workTimer.start()
aServer.processCommunication task.request.body, (error, answer) ->
console.error error if error
toEnd = true
switch answer.action
when 'deliver'
deliverTimer.stop()
toEnd = false
aServer.mutateSharedFunctions () ->
endCommunication task, answer, callback
when 'request'
requestTimer.stop()
if answer.finalized
printReport()
if toEnd
endCommunication task, answer, callback
# Process a task with a HTTP request
processTask = (task, callback) ->
action = task.action
if aServer.getGeneration() isnt actualGeneration
actualGeneration = aServer.getGeneration()
if actualGeneration > 0
progressBar.tick()
if argv.sync and not syncAuth and action is 'request'
# Ask to sync server to continue
sendTakeToSyncServer task, callback
else
# No Sync server continue normal process
processData task, callback
# Read POST content
httpServer.use bodyParser.json limit: '500mb'
httpServer.use bodyParser.urlencoded limit: '500mb', extended: true
# Handle all GET requests
httpServer.get '/', (request, response) ->
response.send('This server only responds POST requests')
# Handle all POST requests
httpServer.post '/', (request, response) ->
# Start general timer
generalTimer.start() if generalTimer.getInitialDate() is 0
# Write in database, parallel to queue process
aServer.writeInDB()
# add a new task to the queue process
newTask =
request : request
response: response
action : request.body.action
aQueue.push newTask,
# Callback when the task finished
() ->
taskFinishedCounter++
workTimer.stop()
startHTTPServer = (port, projectName, database) ->
new Server( database
# Callback when the server is ready for accept request
, projectName, (error) ->
if error
console.error error
else
# Start queue for client requests
aQueue = async.queue(processTask, PARALELL_TASKS)
# Start HTTP server
# Initialize progress bar
progressBar = new progress "[:bar] :percent , :eta m " +
", :current generation of :total",
total: aServer.getGenerationLimit(),
width: 20
httpServer.listen port
console.log 'Server listening on port ' + port
console.log 'Start time :' + new Date
)
saveProject = (projectFile, database) ->
projectsCollection = database.collection('projects')
project = require('./' + projectFile)
projectName = project.name
projectsCollection.findOne { name: projectName }, (error, doc) ->
if error
console.error error
else
if doc != null
console.error 'The project ' + project.name + ' already exists'
database.close()
else
#/ Convert JS functions in Mongo Functions
objName = null
for objName of project
`objName = objName`
if typeof project[objName] == 'function'
project[objName] = mongo.Code(project[objName])
#/ Insert Project and delete population
projectsCollection.insert project, ->
database.dropCollection 'pop_' + projectName, ->
console.log "Project saved #{projectName}"
database.close()
commander.version('1.0.1')
.option('-p, --port <n>', 'Http port for communication with clients', parseInt)
.option('-u, --urlMongo <url>', 'URL for connect with MongoDB')
.option('-s, --save <file>', 'JS file with project description')
.option('-r, --run <projectName>', 'Run a specified project')
.option('-c, --sync <URL>', 'URL coordinator server for MPEA')
.parse process.argv
if commander.port
argv.httpPort = commander.port
if commander.urlMongo
argv.urlMongo = commander.urlMongo
if commander.sync
# argv.urlSync = Commander.urlSync;
argv.sync = true
if commander.run
argv.projectName = commander.run
else
if !commander.save
commander.help()
MongoClient.connect argv.urlMongo, (error, database) ->
if error
console.error error
console.error 'Is MongoDB server running ?'
else
if commander.save
# Save a project
saveProject commander.save, database
else
# Start HTTP server
aServer = startHTTPServer argv.httpPort, argv.projectName, database