1 | _ = require 'lodash'
|
2 | colors = require 'colors'
|
3 | morgan = require 'morgan'
|
4 | express = require 'express'
|
5 | bodyParser = require 'body-parser'
|
6 | cors = require 'cors'
|
7 | errorHandler = require 'errorhandler'
|
8 | meshbluHealthcheck = require 'express-meshblu-healthcheck'
|
9 | SendError = require 'express-send-error'
|
10 | redis = require 'redis'
|
11 | RedisNS = require '@octoblu/redis-ns'
|
12 | debug = require('debug')('meshblu-server-http:server')
|
13 | Router = require './router'
|
14 | {Pool} = require 'generic-pool'
|
15 | PooledJobManager = require 'meshblu-core-pooled-job-manager'
|
16 | JobLogger = require 'job-logger'
|
17 | JobToHttp = require './helpers/job-to-http'
|
18 | PackageJSON = require '../package.json'
|
19 |
|
20 | class Server
|
21 | constructor: (options)->
|
22 | {@disableLogging, @port, @aliasServerUri} = options
|
23 | {@redisUri, @namespace, @jobTimeoutSeconds, @meshbluPort, @meshbluHost} = options
|
24 | {@connectionPoolMaxConnections} = options
|
25 | {@jobLogRedisUri, @jobLogQueue} = options
|
26 | @panic 'missing @jobLogQueue', 2 unless @jobLogQueue?
|
27 | @panic 'missing @jobLogRedisUri', 2 unless @jobLogRedisUri?
|
28 | @panic 'missing @meshbluHost', 2 unless @meshbluHost?
|
29 | @panic 'missing @meshbluPort', 2 unless @meshbluPort?
|
30 |
|
31 | address: =>
|
32 | @server.address()
|
33 |
|
34 | panic: (message, exitCode, error) =>
|
35 | error ?= new Error('generic error')
|
36 | console.error colors.red message
|
37 | console.error error?.stack
|
38 | process.exit exitCode
|
39 |
|
40 | run: (callback) =>
|
41 | app = express()
|
42 | app.use SendError()
|
43 | app.use meshbluHealthcheck()
|
44 | app.use morgan 'dev', immediate: false unless @disableLogging
|
45 | app.use errorHandler()
|
46 | app.use cors()
|
47 | app.use bodyParser.urlencoded limit: '50mb', extended : true
|
48 | app.use bodyParser.json limit : '50mb'
|
49 |
|
50 | jobLogger = new JobLogger
|
51 | jobLogQueue: @jobLogQueue
|
52 | indexPrefix: 'metric:meshblu-server-http'
|
53 | type: 'meshblu-server-http:request'
|
54 | client: redis.createClient(@jobLogRedisUri)
|
55 |
|
56 | connectionPool = @_createConnectionPool(maxConnections: @connectionPoolMaxConnections)
|
57 |
|
58 | jobManager = new PooledJobManager
|
59 | timeoutSeconds: @jobTimeoutSeconds
|
60 | pool: connectionPool
|
61 | jobLogger: jobLogger
|
62 |
|
63 | jobToHttp = new JobToHttp
|
64 |
|
65 | router = new Router {jobManager, jobToHttp, @meshbluHost, @meshbluPort}
|
66 |
|
67 | router.route app
|
68 |
|
69 | @server = app.listen @port, callback
|
70 |
|
71 | stop: (callback) =>
|
72 | @server.close callback
|
73 |
|
74 | _createConnectionPool: ({maxConnections}) =>
|
75 | connectionPool = new Pool
|
76 | max: maxConnections
|
77 | min: 0
|
78 | returnToHead: true
|
79 | create: (callback) =>
|
80 | client = _.bindAll new RedisNS @namespace, redis.createClient(@redisUri)
|
81 |
|
82 | client.on 'end', ->
|
83 | client.hasError = new Error 'ended'
|
84 |
|
85 | client.on 'error', (error) ->
|
86 | client.hasError = error
|
87 | callback error if callback?
|
88 |
|
89 | client.once 'ready', ->
|
90 | callback null, client
|
91 | callback = null
|
92 |
|
93 | destroy: (client) => client.end true
|
94 | validate: (client) => !client.hasError?
|
95 |
|
96 | return connectionPool
|
97 |
|
98 | module.exports = Server
|