Skip to content
This repository has been archived by the owner on Sep 29, 2021. It is now read-only.

Commit

Permalink
Merge pull request #14 from symphonyoss/dev
Browse files Browse the repository at this point in the history
Dev changes
  • Loading branch information
jonfreedman committed Sep 4, 2016
2 parents f47dfe0 + 8287c58 commit 64125b3
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 25 deletions.
3 changes: 3 additions & 0 deletions .codeclimate.yml
Expand Up @@ -2,6 +2,9 @@ engines:
coffeelint:
enabled: true
config: coffeelint.json
exclude_fingerprints:
- 96754c84f43c91090c5cbd8db1db582b
- ce6a82089724a66244f300c2e9918637
fixme:
enabled: true
ratings:
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -44,9 +44,9 @@
"mocha": ">=2.5.3",
"nock": "^8.0.0",
"node-uuid": "^1.4.7",
"semantic-release": "^4.3.5",
"semantic-release": "^6.3.0",
"validate-commit-msg": "^2.6.1",
"yargs": "^4.8.0"
"yargs": "^5.0.0"
},
"config": {
"commitizen": {
Expand Down
57 changes: 36 additions & 21 deletions src/adapter.coffee
Expand Up @@ -19,18 +19,48 @@
Symphony = require './symphony'
{V2Message} = require './message'
memoize = require 'memoizee'
backoff = require 'backoff'
Entities = require('html-entities').XmlEntities
entities = new Entities()

class SymphonyAdapter extends Adapter

constructor: (robot, @shutdownFunc) ->
constructor: (robot, @options = {}) ->
super(robot)
throw new Error('HUBOT_SYMPHONY_HOST undefined') unless process.env.HUBOT_SYMPHONY_HOST
throw new Error('HUBOT_SYMPHONY_PUBLIC_KEY undefined') unless process.env.HUBOT_SYMPHONY_PUBLIC_KEY
throw new Error('HUBOT_SYMPHONY_PRIVATE_KEY undefined') unless process.env.HUBOT_SYMPHONY_PRIVATE_KEY
throw new Error('HUBOT_SYMPHONY_PASSPHRASE undefined') unless process.env.HUBOT_SYMPHONY_PASSPHRASE

@expBackoff = backoff.exponential(initialDelay: 10, maxDelay: 60000)
@expBackoff.on 'backoff', (num, delay) =>
if num > 0
@robot.logger.info "Re-attempting to create datafeed - attempt #{num} after #{delay}ms"
@expBackoff.on 'ready', (num, delay) =>
@symphony.createDatafeed()
.then (response) =>
if response.id?
@robot.logger.info "Created datafeed: #{response.id}"
this.removeAllListeners 'poll'
this.on 'poll', @_pollDatafeed
@emit 'poll', response.id
@robot.logger.debug "First 'poll' event emitted"
@emit 'connected'
@robot.logger.debug "'connected' event emitted"
@expBackoff.reset()
else
@robot.emit 'error', new Error("Unable to create datafeed: #{response}")
@expBackoff.backoff()
.fail (err) =>
@robot.emit 'error', new Error("Unable to create datafeed: #{err}")
@expBackoff.backoff()
@expBackoff.on 'fail', () =>
@robot.logger.info 'Shutting down...'
@options.shutdownFunc()
failAfter = @options.failConnectAfter ? 23 # will time out reconnecting after ~10min
@robot.logger.info "Reconnect attempts = #{failAfter}"
@expBackoff.failAfter(failAfter)

send: (envelope, messages...) ->
@robot.logger.debug "Send"
for message in messages
Expand Down Expand Up @@ -63,29 +93,14 @@ class SymphonyAdapter extends Adapter
hourlyRefresh = memoize @_getUser, {maxAge: 3600000, length: 2}
@userLookup = (userId, streamId) => hourlyRefresh userId, streamId
@_createDatafeed()
.then (response) =>
@emit 'connected'
@robot.logger.debug "'connected' event emitted"
return

close: =>
@robot.logger.debug 'Removing datafeed poller'
this.removeListener 'poll', @_pollDatafeed

_createDatafeed: =>
@symphony.createDatafeed()
.then (response) =>
if response.id?
@robot.logger.info "Created datafeed: #{response.id}"
this.removeAllListeners 'poll'
this.on 'poll', @_pollDatafeed
@emit 'poll', response.id
@robot.logger.debug "First 'poll' event emitted"
else
@robot.emit 'error', new Error("Unable to create datafeed: #{response}")
.fail (err) =>
@robot.emit 'error', new Error("Unable to create datafeed: #{err}")
@shutdownFunc()
@expBackoff.backoff()

_pollDatafeed: (id) =>
# defer execution to ensure we don't go into an infinite polling loop
Expand Down Expand Up @@ -123,7 +138,7 @@ class SymphonyAdapter extends Adapter
@robot.brain.userForId(userId, existing)
existing

exports.use = (robot, shutdownFunc) ->
new SymphonyAdapter robot, shutdownFunc ? () ->
@robot.logger.info 'Shutting down...'
process.exit 1
exports.use = (robot, options = {}) ->
options.shutdownFunc = options.shutdownFunc ? () ->
process.exit 1
new SymphonyAdapter robot, options
17 changes: 16 additions & 1 deletion test/adapter-test.coffee
Expand Up @@ -132,8 +132,23 @@ describe 'Adapter test suite', () ->
done()
adapter.run()

it 'should retry if datafeed cannot be created', (done) ->
nock.datafeedCreateHttp400Count = 1
robot = new FakeRobot
adapter = SymphonyAdapter.use robot
adapter.on 'connected', () ->
assert.isDefined(adapter.symphony)
robot.on 'received', () ->
assert.isAtLeast((m for m in robot.received when m.text is 'Hello World').length, 1)
adapter.close()
done()
adapter.run()

it 'should exit datafeed cannot be created', (done) ->
nock.datafeedCreateHttp400Count = 1
robot = new FakeRobot
adapter = SymphonyAdapter.use robot, -> done()
adapter = SymphonyAdapter.use robot, {
shutdownFunc: -> done()
failConnectAfter: 1
}
adapter.run()
2 changes: 1 addition & 1 deletion test/symphony-test.coffee
Expand Up @@ -127,7 +127,7 @@ describe 'REST API test suite', () ->
assert.equal(1, response.length)
assert.equal(msg2, response[0].message)
.fail (error) ->
assert.fail(0, 1,"Failed with error #{error}")
assert.fail(0, 1, "Failed with error #{error}")

it 'readDatafeed should not fail if no messages are available', () ->
symphony.createDatafeed()
Expand Down

0 comments on commit 64125b3

Please sign in to comment.