Skip to content

Commit

Permalink
Merge pull request #27 from dog-ai/dogbowl
Browse files Browse the repository at this point in the history
Dogbowl
  • Loading branch information
hfreire authored Feb 24, 2017
2 parents 71e386a + 9616630 commit 79ea0da
Show file tree
Hide file tree
Showing 68 changed files with 893 additions and 3,539 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ notifications:
email: false
slack:
secure: aBSLceSDtTG9mcNahHsv60ptf8QKccXLK5wzQROw6BujEZyP6c8Ybn57bZiYzamQX3qoyWdHIgfq6LsP4j1R0ULO9UF5HBVjy9pt2x4lQbepp6fkrrlBe8jCvl1fCiYc1Z2th5qB8LGqiRPAGayu34sz8QM0d0rwMGmF+mQjPo+jatYHRAZeycF04zvhjkXLEXSRjx7S1dzPYgJLDNUcNDrV+Qrex86LjJKwLQgVCFxm1Q48TyY6c2y43dTsd/GOFmZ2i2Vct4WTtbUpsRicJcHORyy1UGx0pVUCH52Z4kJrX4OiMTp1mCVaippUn8VycuNwyNFR57bCvbisi6/PctLUX6oveJnm2WO9kVlGP6UeOo2l3MYO+VjM+0LH8Z0XDSZNNwVJ7qnO/MAZDDMYQZfLQUvx5KNjfPFaVSJRHaKU7qtBn2OfTPX6uO259I44jhIpIC9zECX32USNz3+s/nLW7ZTiK4sD2TR+U+xyhpRm/pFY2mNBC8BJCTVTabPYlOTkIgSXsFXirmBPlufMNrkrmRRxMtby3B1Ur0K19yIB3SpsmNcOcZ29quRVmaktiSCtcpOA2B/pwyoDy/GETi5382CZUu2dAQj6IdQIhEEcrnNn4iADGXpyWom7oFR6TgCwy0Pd9RZ+XBhO03XkrjwbnEMdB/eisKkaufj+16w=
on_success: change
on_failure: always
before_script:
- 'npm prune'
after_success:
Expand Down
20 changes: 2 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "dogbot",
"version": "0.0.0",
"description": "",
"author": "Hugo Freire",
"private": true,
"author": "Hugo Freire <[email protected]>",
"license": "UNLICENSED",
"repository": {
"type": "git",
Expand All @@ -18,16 +19,11 @@
"bluebird": "3.3.3",
"bluebird-retry": "^0.8.0",
"botkit": "^0.2.2",
"cron": "1.0.9",
"express": "4.13.0",
"ffi": "2.0.0",
"firebase": "2.4.2",
"firebase-queue": "1.3.0",
"firebase-token-generator": "2.0.0",
"google-calendar": "1.3.2",
"gosquared": "2.0.2",
"i18n": "^0.8.3",
"intimidate": "1.2.0",
"ip": "0.3.3",
"isomorphic-fetch": "^2.2.1",
"kue": "0.10.5",
Expand All @@ -37,30 +33,18 @@
"locks": "^0.2.2",
"lodash": "3.10.1",
"macvendor": "0.1.1",
"memory-stream": "0.0.3",
"moment": "2.15.1",
"moment-timezone": "0.4.0",
"nconf": "0.7.1",
"node-record-lpcm16": "^0.1.8",
"node-uuid": "1.4.7",
"node-wit": "2.0.0",
"node-wolfram": "0.0.1",
"passport": "0.2.2",
"passport-google-oauth": "0.2.0",
"passport-oauth2-refresh": "0.4.0",
"plotly": "1.0.2",
"procfs-stats": "0.0.4",
"redis": "2.4.2",
"request": "^2.75.0",
"rollbar": "0.5.16",
"s3": "4.4.0",
"sendgrid": "2.0.0",
"snowboy": "^1.1.0",
"split": "1.0.0",
"sqlite3": "3.1.4",
"stack-trace": "0.0.9",
"winston": "2.2.0",
"wireless-tools": "0.14.0",
"xml2js": "0.4.15"
},
"devDependencies": {
Expand Down
12 changes: 5 additions & 7 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const SECRET = process.env.DOGBOT_SECRET
const WATCHDOG_USEC = process.env.WATCHDOG_USEC

const { Logger } = require('./utils')
const { Bot } = require('./bot')

const bot = new Bot()
const Bot = require('./bot')

// shutdown gracefully
const stopAndExit = () => {
bot.stop()
Bot.stop()
.then(() => Logger.info('Stopped dogbot'))
.finally(() => process.exit(0))
}
Expand All @@ -31,7 +29,7 @@ process.on('SIGABRT', () => process.exit(1)) // force immediate exit, i.e. syste

Logger.info('Starting dogbot')

bot.start(SECRET)
Bot.start(SECRET)
.then(() => {
if (process.platform === 'linux') {
require('./utils/systemd').sdNotify(0, 'READY=1', (error) => {
Expand All @@ -50,7 +48,7 @@ bot.start(SECRET)
}
}

bot.heartbeat(WATCHDOG_USEC, heartbeat)
Bot.heartbeat(WATCHDOG_USEC, heartbeat)
.then((interval) => {
Logger.info(`Sending a heartbeat every ${interval} seconds`)
})
Expand Down
3 changes: 1 addition & 2 deletions src/apps/brain.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const App = require('./app')

class Brain extends App {
constructor () {
super('brain', [], [
{ type: 'action', name: 'slap' },
{ type: 'email', name: 'sendgrid' },
{ type: 'user', name: 'invite' }
])
Expand Down
73 changes: 51 additions & 22 deletions src/bot/bot.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,83 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const Promise = require('bluebird')

const { Logger } = require('../utils')

const { Sync } = require('./sync')
const Sync = require('./sync')
const Worker = require('./worker')
const Heartbeat = require('./heartbeat')
const Communication = require('./communication')

class Bot {
constructor () {
this._sync = new Sync()
this._worker = new Worker()
this._heartbeat = new Heartbeat()
}

start (secret) {
if (!secret) {
return Promise.reject(new Error('invalid secret'))
}

return this._worker.start()
return Worker.start()
.then(() => {
// unchain so we don't get blocked by not having an internet connection
this._sync.start(secret)
Sync.start(secret)
.catch(Logger.error)
})
.catch(Logger.error)
}

stop () {
return this._sync.stop()
.then(() => this._worker.stop())
.then(() => this._heartbeat.stop())
return Sync.stop()
.then(() => Worker.stop())
.then(() => Heartbeat.stop())
.catch(Logger.error)
}

heartbeat (interval, heartbeat) {
try {
const healthChecks = [ this._sync.healthCheck(), this._worker.healthCheck() ]
on (event, callback) {
Communication.on(event, callback)
}

const realInterval = this._heartbeat.start(interval, heartbeat, () => Promise.all(healthChecks))
once (event, callback) {
Communication.once(event, callback)
}

return Promise.resolve(realInterval)
} catch (error) {
return Promise.reject(error)
}
removeListener (event, callback) {
Communication.removeListener(event, callback)
}

removeAllListeners (event) {
Communication.removeAllListeners(event)
}

emit (event, ...params) {
Communication.emit(event, ...params)
}

emitAsync (event, ...params) {
return Communication.emitAsync(event, ...params)
}

getCompanyId () {
return Sync.getCompanyId()
}

enqueueJob (event, params, options, callbacks) {
return Worker.enqueueJob(event, params, options, callbacks)
}

dequeueJob (event) {
return Worker.dequeueJob(event)
}

enqueueTask (event, params) {
return Sync.enqueueTask(event, params)
}

heartbeat (interval, heartbeat) {
const healthChecks = [ Sync.healthCheck(), Worker.healthCheck() ]

return Heartbeat.start(interval, heartbeat, () => Promise.all(healthChecks))
}
}

module.exports = Bot
module.exports = new Bot()
2 changes: 1 addition & 1 deletion src/utils/communication.js → src/bot/communication.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const Promise = require('bluebird')
Expand Down
58 changes: 34 additions & 24 deletions src/bot/heartbeat.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const Promise = require('bluebird')

const { Communication } = require('../utils')
const Worker = require('./worker')
const Communication = require('./communication')

function run (params, callback) {
this._healthCheck()
Expand All @@ -15,39 +16,48 @@ function run (params, callback) {

class Heartbeat {
start (interval, heartbeat, healthCheck) {
if (this._isRunning) {
throw new Error('already started')
}
return new Promise((resolve, reject) => {
if (this._isRunning) {
return reject(new Error('already started'))
}

if (!interval > 0) {
throw new Error('invalid interval')
}
if (!interval > 0) {
return reject(new Error('invalid interval'))
}

this._interval = interval / 2
this._interval = interval / 2

this._heartbeat = Promise.promisify(heartbeat)
this._healthCheck = healthCheck
this._heartbeat = Promise.promisify(heartbeat)
this._healthCheck = healthCheck

Communication.on('bot:heartbeat', run.bind(this))
Communication.emit('worker:job:enqueue', 'bot:heartbeat', null, { schedule: this._interval + ' seconds' })
Communication.on('bot:heartbeat', run.bind(this))

this._isRunning = true
const options = { schedule: this._interval + ' seconds' }
Worker.enqueueJob('bot:heartbeat', null, options)

return this._interval
this._isRunning = true

resolve(this._interval)
})
}

stop () {
if (!this._isRunning) {
return
}
return new Promise((resolve, reject) => {
if (!this._isRunning) {
return resolve()
}

Worker.dequeueJob('bot:heartbeat')

Communication.removeListener('bot:heartbeat', run.bind(this))

Communication.emit('worker:job:dequeue', 'bot:heartbeat')
Communication.removeListener('bot:heartbeat', run.bind(this))
delete this._interval
delete this._heartbeat
delete this._isRunning

delete this._interval
delete this._heartbeat
delete this._isRunning
resolve()
})
}
}

module.exports = Heartbeat
module.exports = new Heartbeat()
6 changes: 2 additions & 4 deletions src/bot/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

module.exports = {
Bot: require('./bot')
}
module.exports = require('./bot')
6 changes: 2 additions & 4 deletions src/bot/sync/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

module.exports = {
Sync: require('./sync')
}
module.exports = require('./sync')
10 changes: 7 additions & 3 deletions src/bot/sync/modules.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/*
* Copyright (C) 2016, Hugo Freire <[email protected]>. All rights reserved.
* Copyright (C) 2017, Hugo Freire <[email protected]>. All rights reserved.
*/

const ENVIRONMENT = process.env.DOGBOT_ENVIRONMENT || 'local'

const _ = require('lodash')
const Promise = require('bluebird')

const Worker = require('../worker')
const Communication = require('../communication')

const moment = require('moment-timezone')

const { Communication, Logger } = require('../../utils')
const { Logger } = require('../../utils')

class Modules {
start (firebase, dogId, companyId) {
Expand All @@ -26,7 +29,8 @@ class Modules {

// start an outgoing periodic sync job every 10 minutes
Communication.on('sync:outgoing:periodic', this._periodicOutgoingSynchronization.bind(this))
Communication.emit('worker:job:enqueue', 'sync:outgoing:periodic', null, { schedule: '10 minutes' })
const options = { schedule: '10 minutes' }
Worker.enqueueJob('sync:outgoing:periodic', null, options)

// listen for incoming sync callback registrations
Communication.on('sync:incoming:register:setup', this._registerIncomingSynchronization.bind(this))
Expand Down
Loading

0 comments on commit 79ea0da

Please sign in to comment.