Remove image actor service as not needed
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
server: 'dar-test-server',
|
server: 'dar-test-server',
|
||||||
api: 'dar-test-api',
|
api: 'dar-test-api',
|
||||||
email: 'dar-test-email',
|
email: 'dar-test-email',
|
||||||
image: 'dar-test-image',
|
|
||||||
},
|
},
|
||||||
uri: {
|
uri: {
|
||||||
mongo: 'mongodb://localhost/dar-test-v1',
|
mongo: 'mongodb://localhost/dar-test-v1',
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
server: 'dar-server',
|
server: 'dar-server',
|
||||||
api: 'dar-api',
|
api: 'dar-api',
|
||||||
email: 'dar-email',
|
email: 'dar-email',
|
||||||
image: 'dar-image',
|
|
||||||
},
|
},
|
||||||
uri: {
|
uri: {
|
||||||
mongo: 'mongodb://localhost/dar-v1',
|
mongo: 'mongodb://localhost/dar-v1',
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
"test": "jest",
|
"test": "jest",
|
||||||
"actor:api": "monzilla 'src/api/**/*.js:src/database/**/*.js' -- babel-node src/api/index.js",
|
"actor:api": "monzilla 'src/api/**/*.js:src/database/**/*.js' -- babel-node src/api/index.js",
|
||||||
"actor:api:debug": "babel-node --inspect-brk src/api/index.js",
|
"actor:api:debug": "babel-node --inspect-brk src/api/index.js",
|
||||||
"actor:image": "monzilla 'src/image/**/*.js:src/(message-service|database)/**/*.js' -- babel-node src/image/index.js",
|
|
||||||
"actor:image:debug": "babel-node --inspect-brk src/image/index.js",
|
|
||||||
"actor:email": "monzilla 'src/email/**/*.js:src/(message-service|database)/**/*.js' -- babel-node src/email/index.js",
|
"actor:email": "monzilla 'src/email/**/*.js:src/(message-service|database)/**/*.js' -- babel-node src/email/index.js",
|
||||||
"actor:email:debug": "babel-node --inspect-brk src/email/index.js"
|
"actor:email:debug": "babel-node --inspect-brk src/email/index.js"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
import childProcess from 'child_process'
|
import childProcess from "child_process"
|
||||||
import path from 'path'
|
import path from "path"
|
||||||
import timers from 'timers'
|
import timers from "timers"
|
||||||
import autobind from 'autobind-decorator'
|
import autobind from "autobind-decorator"
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
export class ServerTool {
|
export class ServerTool {
|
||||||
constructor(toolName, log) {
|
constructor(toolName, log) {
|
||||||
this.toolName = toolName
|
this.toolName = toolName
|
||||||
this.log = log
|
this.log = log
|
||||||
this.actors = [
|
this.actors = [{ name: "api" }, { name: "email" }]
|
||||||
{ name: 'api' },
|
|
||||||
{ name: 'email' },
|
|
||||||
{ name: 'image' },
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restart(actor) {
|
restart(actor) {
|
||||||
@@ -27,7 +23,11 @@ export class ServerTool {
|
|||||||
const backOffTime = (Math.pow(2, Math.min(actor.backOff, 7)) - 1) * 1000
|
const backOffTime = (Math.pow(2, Math.min(actor.backOff, 7)) - 1) * 1000
|
||||||
|
|
||||||
if (backOffTime > 0) {
|
if (backOffTime > 0) {
|
||||||
this.log.warn(`Actor '${actor.name}' died quickly, waiting ${Math.floor(backOffTime / 1000)} seconds to restart`)
|
this.log.warn(
|
||||||
|
`Actor '${actor.name}' died quickly, waiting ${Math.floor(
|
||||||
|
backOffTime / 1000
|
||||||
|
)} seconds to restart`
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
this.log.warn(`Actor ${actor.name} died, restarting`)
|
this.log.warn(`Actor ${actor.name} died, restarting`)
|
||||||
}
|
}
|
||||||
@@ -36,9 +36,9 @@ export class ServerTool {
|
|||||||
actor.starts += 1
|
actor.starts += 1
|
||||||
actor.startTime = Date.now()
|
actor.startTime = Date.now()
|
||||||
actor.proc = childProcess.fork(actor.modulePath)
|
actor.proc = childProcess.fork(actor.modulePath)
|
||||||
actor.proc.on('exit', (code, signal) => {
|
actor.proc.on("exit", (code, signal) => {
|
||||||
// Don't restart if the exit was clean or Control+C
|
// Don't restart if the exit was clean or Control+C
|
||||||
if (code === 0 || signal === 'SIGINT') {
|
if (code === 0 || signal === "SIGINT") {
|
||||||
this.log.info(`Actor ${actor.name} terminated normally`)
|
this.log.info(`Actor ${actor.name} terminated normally`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -53,43 +53,53 @@ export class ServerTool {
|
|||||||
let promises = []
|
let promises = []
|
||||||
|
|
||||||
this.actors.forEach((actor) => {
|
this.actors.forEach((actor) => {
|
||||||
promises.push(new Promise((resolve, reject) => {
|
promises.push(
|
||||||
actor.modulePath = path.join(__dirname, actor.name)
|
new Promise((resolve, reject) => {
|
||||||
actor.startTime = Date.now()
|
actor.modulePath = path.join(__dirname, actor.name)
|
||||||
actor.backOff = 0
|
actor.startTime = Date.now()
|
||||||
actor.timeToInit = actor.timeToInit || 3000
|
actor.backOff = 0
|
||||||
actor.proc = childProcess.fork(actor.modulePath)
|
actor.timeToInit = actor.timeToInit || 3000
|
||||||
actor.proc.on('exit', (code, signal) => {
|
actor.proc = childProcess.fork(actor.modulePath)
|
||||||
const timeSinceStart = Date.now() - actor.startTime
|
actor.proc.on("exit", (code, signal) => {
|
||||||
|
const timeSinceStart = Date.now() - actor.startTime
|
||||||
|
|
||||||
if (timeSinceStart < actor.timeToInit) {
|
if (timeSinceStart < actor.timeToInit) {
|
||||||
this.log.error(`Actor '${actor.name}' exited during initialization`)
|
this.log.error(
|
||||||
|
`Actor '${actor.name}' exited during initialization`
|
||||||
|
)
|
||||||
|
|
||||||
if (this.actors) {
|
if (this.actors) {
|
||||||
this.actors.forEach((otherActor) => {
|
this.actors.forEach((otherActor) => {
|
||||||
if (otherActor !== actor) {
|
if (otherActor !== actor) {
|
||||||
this.log.info(`Terminating actor ${actor.name}, pid ${otherActor.proc.pid}`)
|
this.log.info(
|
||||||
otherActor.proc.kill('SIGINT')
|
`Terminating actor ${actor.name}, pid ${
|
||||||
otherActor.proc = null
|
otherActor.proc.pid
|
||||||
}
|
}`
|
||||||
})
|
)
|
||||||
|
otherActor.proc.kill("SIGINT")
|
||||||
|
otherActor.proc = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
actor.proc = null
|
actor.proc = null
|
||||||
this.actors = null
|
this.actors = null
|
||||||
|
}
|
||||||
|
|
||||||
|
return reject(
|
||||||
|
new Error("All actors must initialize on first start")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return reject(new Error('All actors must initialize on first start'))
|
this.restart(actor)
|
||||||
}
|
})
|
||||||
|
timers.setTimeout(() => {
|
||||||
this.restart(actor)
|
if (actor.proc) {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
}, actor.timeToInit)
|
||||||
|
this.log.info(`Started actor '${actor.name}', pid ${actor.proc.pid}`)
|
||||||
})
|
})
|
||||||
timers.setTimeout(() => {
|
) // new Promise()
|
||||||
if (actor.proc) {
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
}, actor.timeToInit)
|
|
||||||
this.log.info(`Started actor '${actor.name}', pid ${actor.proc.pid}`)
|
|
||||||
})) // new Promise()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class SendMessageTool {
|
|||||||
usage: ${this.toolName} [options] <file>
|
usage: ${this.toolName} [options] <file>
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-x --exchange <exchange> Exchange to send the message too, e.g. tmr-image
|
-x --exchange <exchange> Exchange to send the message too
|
||||||
-t --type <message-type> The type of the message content
|
-t --type <message-type> The type of the message content
|
||||||
`)
|
`)
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ export let userSchema = new Schema(
|
|||||||
unique: true,
|
unique: true,
|
||||||
},
|
},
|
||||||
newEmail: { type: String, match: regExpPattern.email },
|
newEmail: { type: String, match: regExpPattern.email },
|
||||||
thumbnailImageId: { type: Schema.Types.ObjectId },
|
|
||||||
emailToken: {
|
emailToken: {
|
||||||
type: {
|
type: {
|
||||||
value: String,
|
value: String,
|
||||||
@@ -71,8 +70,6 @@ userSchema.methods.toClient = function(authUser) {
|
|||||||
_id: this._id,
|
_id: this._id,
|
||||||
email: this.email,
|
email: this.email,
|
||||||
emailValidated: !!this.emailToken !== true,
|
emailValidated: !!this.emailToken !== true,
|
||||||
imageId: this.imageId,
|
|
||||||
thumbnailImageId: this.thumbnailImageId,
|
|
||||||
firstName: this.firstName,
|
firstName: this.firstName,
|
||||||
lastName: this.lastName,
|
lastName: this.lastName,
|
||||||
administrator: this.administrator,
|
administrator: this.administrator,
|
||||||
|
|||||||
@@ -1,298 +0,0 @@
|
|||||||
import Canvas from 'canvas'
|
|
||||||
import fs from 'fs'
|
|
||||||
import util from 'util'
|
|
||||||
import createError from 'http-errors'
|
|
||||||
import autobind from 'autobind-decorator'
|
|
||||||
import stream from 'stream'
|
|
||||||
|
|
||||||
function streamToBuffer(readable) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
var chunks = []
|
|
||||||
var writeable = new stream.Writable()
|
|
||||||
|
|
||||||
writeable._write = function (chunk, enc, done) {
|
|
||||||
chunks.push(chunk)
|
|
||||||
done()
|
|
||||||
}
|
|
||||||
|
|
||||||
readable.on('end', function () {
|
|
||||||
resolve(Buffer.concat(chunks))
|
|
||||||
})
|
|
||||||
|
|
||||||
readable.on('error', (err) => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
readable.pipe(writeable);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function pipeToGridFS(readable, gfsWriteable) {
|
|
||||||
const promise = new Promise((resolve, reject) => {
|
|
||||||
readable.on('error', (error) => {
|
|
||||||
reject(error)
|
|
||||||
})
|
|
||||||
gfsWriteable.on('error', (error) => {
|
|
||||||
reject(error)
|
|
||||||
})
|
|
||||||
gfsWriteable.on('close', (file) => {
|
|
||||||
resolve(file)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
readable.pipe(gfsWriteable)
|
|
||||||
return promise
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadImage(buf) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const image = new Canvas.Image()
|
|
||||||
|
|
||||||
function cleanup () {
|
|
||||||
image.onload = null
|
|
||||||
image.onerror = null
|
|
||||||
}
|
|
||||||
|
|
||||||
image.onload = () => {
|
|
||||||
cleanup();
|
|
||||||
resolve(image)
|
|
||||||
}
|
|
||||||
image.onerror = () => {
|
|
||||||
cleanup();
|
|
||||||
reject(new Error(`Failed to load the image "${buf}"`))
|
|
||||||
}
|
|
||||||
|
|
||||||
image.src = buf
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derived from https://stackoverflow.com/questions/20600800/js-client-side-exif-orientation-rotate-and-mirror-jpeg-images
|
|
||||||
function getExifOrientation(buf) {
|
|
||||||
if (buf.length < 2 || buf.readUInt16BE(0) != 0xFFD8) {
|
|
||||||
return -2
|
|
||||||
}
|
|
||||||
|
|
||||||
let length = buf.byteLength
|
|
||||||
let offset = 2
|
|
||||||
|
|
||||||
while (offset < length) {
|
|
||||||
let marker = buf.readUInt16BE(offset)
|
|
||||||
offset += 2
|
|
||||||
|
|
||||||
if (marker == 0xFFE1) {
|
|
||||||
if (buf.readUInt32BE(offset += 2) != 0x45786966) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
let little = (buf.readUInt16BE(offset += 6) == 0x4949)
|
|
||||||
offset += (little ? buf.readUInt32LE(offset + 4) : buf.readUInt32BE(offset + 4))
|
|
||||||
|
|
||||||
const numTags = (little ? buf.readUInt16LE(offset) : buf.readUInt16BE(offset))
|
|
||||||
|
|
||||||
offset += 2
|
|
||||||
for (let i = 0; i < numTags; i++) {
|
|
||||||
let val = (little ? buf.readUInt16LE(offset + (i * 12)) : buf.readUInt16BE(offset + (i * 12)))
|
|
||||||
|
|
||||||
if (val === 0x0112) {
|
|
||||||
return (little ? buf.readUInt16LE(offset + (i * 12) + 8) : buf.readUInt16BE(offset + (i * 12) + 8))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((marker & 0xFF00) != 0xFF00) {
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
offset += buf.readUInt16BE(offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeOrientation(image, orientation) {
|
|
||||||
let width = image.width
|
|
||||||
let height = image.height
|
|
||||||
let canvas = new Canvas(width, height)
|
|
||||||
let ctx = canvas.getContext("2d")
|
|
||||||
|
|
||||||
if (4 < orientation && orientation < 9) {
|
|
||||||
canvas.width = height
|
|
||||||
canvas.height = width
|
|
||||||
} else {
|
|
||||||
canvas.width = width
|
|
||||||
canvas.height = height
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (orientation) {
|
|
||||||
case 2: ctx.transform(-1, 0, 0, 1, width, 0); break
|
|
||||||
case 3: ctx.transform(-1, 0, 0, -1, width, height ); break
|
|
||||||
case 4: ctx.transform(1, 0, 0, -1, 0, height ); break
|
|
||||||
case 5: ctx.transform(0, 1, 1, 0, 0, 0); break
|
|
||||||
case 6: ctx.transform(0, 1, -1, 0, height , 0); break
|
|
||||||
case 7: ctx.transform(0, -1, -1, 0, height , width); break
|
|
||||||
case 8: ctx.transform(0, -1, 1, 0, 0, width); break
|
|
||||||
default: return Promise.resolve(image)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.drawImage(image, 0, 0)
|
|
||||||
return loadImage(canvas.toBuffer())
|
|
||||||
}
|
|
||||||
|
|
||||||
@autobind
|
|
||||||
export class ImageHandlers {
|
|
||||||
constructor(container) {
|
|
||||||
this.db = container.db
|
|
||||||
this.log = container.log
|
|
||||||
}
|
|
||||||
|
|
||||||
scaleImage(options) {
|
|
||||||
const {
|
|
||||||
newWidth = 400,
|
|
||||||
newHeight = 100,
|
|
||||||
scaleMode = 'scaleToFill',
|
|
||||||
inputFile,
|
|
||||||
inputAssetId,
|
|
||||||
outputFile
|
|
||||||
} = options
|
|
||||||
|
|
||||||
if (!inputFile && !inputAssetId) {
|
|
||||||
return Promise.reject(createError.BadRequest(`No inputAssetId or inputFile given`))
|
|
||||||
}
|
|
||||||
|
|
||||||
let canvas = new Canvas(newWidth, newHeight)
|
|
||||||
let ctx = canvas.getContext("2d")
|
|
||||||
|
|
||||||
ctx.imageSmoothingEnabled = true
|
|
||||||
|
|
||||||
let loadPromise = null
|
|
||||||
|
|
||||||
if (inputFile) {
|
|
||||||
loadPromise = util.promisify(fs.readFile)(inputFile)
|
|
||||||
} else {
|
|
||||||
loadPromise = streamToBuffer(this.db.gridfs.createReadStream({ _id: inputAssetId }))
|
|
||||||
}
|
|
||||||
|
|
||||||
let orientation
|
|
||||||
|
|
||||||
return loadPromise.then((buf) => {
|
|
||||||
orientation = getExifOrientation(buf)
|
|
||||||
return loadImage(buf)
|
|
||||||
}).then((img) => {
|
|
||||||
return normalizeOrientation(img, orientation)
|
|
||||||
}).then((img) => {
|
|
||||||
let x = 0
|
|
||||||
let y = 0
|
|
||||||
let scale = 1
|
|
||||||
|
|
||||||
switch (scaleMode) {
|
|
||||||
case 'aspectFill':
|
|
||||||
if (img.width - newWidth > img.height - newHeight) {
|
|
||||||
scale = newHeight / img.height
|
|
||||||
x = -(img.width * scale - newWidth) / 2
|
|
||||||
} else {
|
|
||||||
scale = newWidth / img.width
|
|
||||||
y = -(img.height * scale - newHeight) / 2
|
|
||||||
}
|
|
||||||
ctx.drawImage(img, x, y, img.width * scale, img.height * scale)
|
|
||||||
break
|
|
||||||
case 'aspectFit':
|
|
||||||
if (img.width - newWidth > img.height - newHeight) {
|
|
||||||
scale = newWidth / img.width
|
|
||||||
y = (newHeight - img.height * scale) / 2
|
|
||||||
} else {
|
|
||||||
scale = newHeight / img.height
|
|
||||||
x = (newWidth - img.width * scale) / 2
|
|
||||||
}
|
|
||||||
ctx.drawImage(img, x, y, img.width * scale, img.height * scale)
|
|
||||||
break
|
|
||||||
case 'scaleToFill':
|
|
||||||
default:
|
|
||||||
ctx.drawImage(img, 0, 0, newWidth, newHeight)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
let savePromise = null
|
|
||||||
let readable = canvas.createPNGStream()
|
|
||||||
let writeable = null
|
|
||||||
|
|
||||||
if (outputFile) {
|
|
||||||
writeable = fs.createWriteStream(outputFile)
|
|
||||||
} else {
|
|
||||||
const _id = this.db.newObjectId()
|
|
||||||
writeable = this.db.gridfs.createWriteStream({
|
|
||||||
_id,
|
|
||||||
filename: _id + '.png',
|
|
||||||
content_type: 'image/png',
|
|
||||||
metadata: {
|
|
||||||
scaledFrom: this.db.newObjectId(inputAssetId),
|
|
||||||
width: newWidth,
|
|
||||||
height: newHeight
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return pipeToGridFS(readable, writeable).then((file) => {
|
|
||||||
let res = {}
|
|
||||||
if (outputFile) {
|
|
||||||
res.outputFile = outputFile
|
|
||||||
} else if (file) {
|
|
||||||
res.outputAssetId = file._id
|
|
||||||
}
|
|
||||||
return Promise.resolve(res)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
createPlaceholder(options) {
|
|
||||||
const {
|
|
||||||
width = 400,
|
|
||||||
height = 100,
|
|
||||||
fontSize = 36,
|
|
||||||
fontName = 'helvetica neue, arial black, sans serif',
|
|
||||||
fontWeight = 'bold',
|
|
||||||
background = '#1B1B1B',
|
|
||||||
foreground = '#333333',
|
|
||||||
outputFile
|
|
||||||
} = options
|
|
||||||
|
|
||||||
let canvas = new Canvas(width, height)
|
|
||||||
let ctx = canvas.getContext("2d")
|
|
||||||
const text = `${width}x${height}`
|
|
||||||
|
|
||||||
ctx.fillStyle = background
|
|
||||||
ctx.fillRect(0, 0, width, height)
|
|
||||||
|
|
||||||
ctx.font = `${fontWeight} ${fontSize}px ${fontName}`
|
|
||||||
ctx.fillStyle = foreground
|
|
||||||
const tm = ctx.measureText(text)
|
|
||||||
|
|
||||||
if (tm.width <= width / 2 && fontSize <= height / 2) {
|
|
||||||
ctx.textAlign = 'center'
|
|
||||||
ctx.textBaseline = 'middle'
|
|
||||||
ctx.fillText(text, width / 2, height / 2, width)
|
|
||||||
}
|
|
||||||
|
|
||||||
let promise = null
|
|
||||||
let readable = canvas.createPNGStream()
|
|
||||||
let writeable = null
|
|
||||||
|
|
||||||
if (outputFile) {
|
|
||||||
writeable = fs.createWriteStream(outputFile)
|
|
||||||
} else {
|
|
||||||
const _id = this.db.newObjectId()
|
|
||||||
writeable = this.db.gridfs.createWriteStream({
|
|
||||||
_id,
|
|
||||||
filename: `${width}x${height}.png`,
|
|
||||||
content_type: 'image/png',
|
|
||||||
metadata: {
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return pipeToGridFS(readable, writeable).then((file) => {
|
|
||||||
let res = {}
|
|
||||||
if (outputFile) {
|
|
||||||
res.outputFile = outputFile
|
|
||||||
} else if (file) {
|
|
||||||
res.outputAssetId = file._id
|
|
||||||
}
|
|
||||||
return Promise.resolve(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import config from "config"
|
|
||||||
import pino from "pino"
|
|
||||||
import * as pinoExpress from "pino-pretty-express"
|
|
||||||
import { DB } from "../database"
|
|
||||||
import { MS } from "../message-service"
|
|
||||||
import { ImageHandlers } from "./ImageHandlers"
|
|
||||||
import path from "path"
|
|
||||||
import fs from "fs"
|
|
||||||
|
|
||||||
const serviceName = config.get("serviceName.image")
|
|
||||||
const isProduction = process.env.NODE_ENV === "production"
|
|
||||||
let log = null
|
|
||||||
|
|
||||||
if (isProduction) {
|
|
||||||
log = pino(
|
|
||||||
{ name: serviceName },
|
|
||||||
fs.createWriteStream(path.join(config.get("logDir"), serviceName + ".log"))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
const pretty = pinoExpress.pretty({})
|
|
||||||
pretty.pipe(process.stdout)
|
|
||||||
log = pino({ name: serviceName }, pretty)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ms = new MS(serviceName, { durable: false }, log)
|
|
||||||
const db = new DB()
|
|
||||||
let container = { db, ms, log }
|
|
||||||
const mongoUri = config.get("uri.mongo")
|
|
||||||
const amqpUri = config.get("uri.amqp")
|
|
||||||
|
|
||||||
Promise.all([db.connect(mongoUri), ms.connect(amqpUri)])
|
|
||||||
.then(() => {
|
|
||||||
log.info(`Connected to MongoDB at ${mongoUri}`)
|
|
||||||
log.info(`Connected to RabbitMQ at ${amqpUri}`)
|
|
||||||
|
|
||||||
container = {
|
|
||||||
...container,
|
|
||||||
handlers: new ImageHandlers(container),
|
|
||||||
}
|
|
||||||
|
|
||||||
ms.listen(container.handlers)
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
log.error(isProduction ? err.message : err)
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user