Ind.ie is now Small Technology Foundation.
Commit 718c95ad authored by Aral Balkan's avatar Aral Balkan

Integrated new pulse node with better process handling. Closes #80. Fixed...

Integrated new pulse node with better process handling. Closes #80. Fixed promisification bugs using fs-extra-as-promised. Closes #82. Fixed startup process regressions. Closes #83. Now saving data schema version in the database on account creation. Closes #84. Replaced Bluebird with Thrush. Closes #85.
parent d9924709
......@@ -22,9 +22,9 @@
util = require 'util'
assert = require 'assert'
fs = require 'fs-extra'
path = require 'path-extra'
Promise = require 'thrush'
fs = require 'fs-extra-as-promised'
path = require 'path-extra'
request = require 'superagent-as-promised'
PulseConfig = (require 'pulse-node').Config
......@@ -35,18 +35,7 @@ MainModel = require './MainModel'
printIt = require 'printit'
log = printIt {prefix: 'Heartbeat Node: Commands', date: true}
# Array::remove = (obj) ->
# @filter (el) -> el isnt obj
# # fs.exists cannot be automatically promisified
# fs.existsAsync = (filePath)->
# return new Promise ((fulfill, reject) ->
# exists = fs.existsSync(filePath)
# process.nextTick(->
# fulfill(exists)
# )
# )
database = require './database'
#
# Commands
......@@ -55,7 +44,7 @@ log = printIt {prefix: 'Heartbeat Node: Commands', date: true}
# Implement properties (with getter/setters) on the Function prototype
# (Thanks https://gist.github.com/reversepanda/5814547)
Function::property = (prop, desc) ->
Object.defineProperty @prototype, prop, desc
Object.defineProperty @prototype, prop, desc
class Commands
......@@ -93,13 +82,16 @@ class Commands
# Pulse API reference is injected in by the owner.
pulseAPI: null
# App config
config: null
constructor: (delegate, pulseAPI, debug, waystoneURL, invitationsURL) ->
constructor: (delegate, pulseAPI, debug, waystoneURL, invitationsURL, config) ->
@delegate = delegate
@pulseAPI = pulseAPI
@waystoneURL = waystoneURL
@invitationsURL = invitationsURL
@config = config
console.log "ℹ️ Commands: debug mode to #{debug}:\n\n\tWaystone URL: #{@waystoneURL}\n\tInvitations URL: #{@invitationsURL}\n"
console.log "ℹ️ Commands: delegate: #{delegate}, Pulse API: #{pulseAPI}"
......@@ -255,74 +247,105 @@ class Commands
log.info("Success: Generated Pulse. Device ID: #{deviceID}")
@makeWaystoneAccount(id, accountHandle, deviceID, invitationCode)
.then (response) =>
#
# Put the current data schema version metadata to the database.
#
console.log "Saving data schema version #{@config.dataSchemaVersion} in the database."
meta = database.withSublevelsAndPromises.sublevel 'meta'
meta.put 'dataSchemaVersion', @config.dataSchemaVersion
.then =>
console.log "Data schema version saved."
#
# Make the Waystone account.
#
console.log "id: #{id}, accountHandle: #{accountHandle}, deviceID: #{deviceID}, invitationCode: #{invitationCode}"
@makeWaystoneAccount(id, accountHandle, deviceID, invitationCode)
.then (response) =>
console.log "Response in makeWaystoneAccount:"
console.log response
if response.error
#
# Error: Could not create Waystone account.
#
log.error("Error: Could not create Waystone account.")
console.log "Response in makeWaystoneAccount:"
console.log response
responseObject =
id: id,
response: response
if response.error
@ws.send(JSON.stringify(responseObject), {binary: true})
#
# Error: Could not create Waystone account.
#
return false
log.error("Error: Could not create Waystone account.")
else
responseObject =
id: id,
response: response
#
# Success: Waystone account created.
#
@ws.send(JSON.stringify(responseObject), {binary: true})
log.info("Success: Waystone account created.")
return false
waystoneDeviceID = response.waystoneDeviceID
else
waystoneURLWithoutProcol = @waystoneURL.replace('http://', '')
waystoneURLWithoutProcol = waystoneURLWithoutProcol.replace('https://', '')
#
# Success: Waystone account created.
#
PulseConfig.initialisePulse(accountHandle, waystoneDeviceID, waystoneURLWithoutProcol).then (success) =>
log.info("Success: Waystone account created.")
if success
waystoneDeviceID = response.waystoneDeviceID
log.info("Success: Pulse initialised.")
waystoneURLWithoutProcol = @waystoneURL.replace('http://', '')
waystoneURLWithoutProcol = waystoneURLWithoutProcol.replace('https://', '')
PulseConfig.initialisePulse(accountHandle, waystoneDeviceID, waystoneURLWithoutProcol).then (success) =>
# Save a reference to the accountHandle in the main application singleton
(new MainModel).accountHandle = accountHandle
if success
# Success: Pulse initialised. We’re done here.
responseObject =
id: id,
response:
deviceID: deviceID
accountHandle: accountHandle
log.info("Success: Pulse initialised.")
@ws.send(JSON.stringify(responseObject), {binary: true})
# Save a reference to the accountHandle in the main application singleton
(new MainModel).accountHandle = accountHandle
return true
# Success: Pulse initialised. We’re done here.
responseObject =
id: id,
response:
deviceID: deviceID
accountHandle: accountHandle
else
@ws.send(JSON.stringify(responseObject), {binary: true})
log.error("Error: Could not initialise Pulse.")
return true
# Error: Could not initialise Pulse.
responseObject =
id: id
response:
error: true
errorMessage: "Could not initialise Pulse."
else
@ws.send(JSON.stringify(responseObject), {binary: true})
return false
.catch (error) =>
#
# Error: Could not save data schema version in the database.
#
log.error("Error: Could not initialise Pulse.")
errorMessage = "Could not save data schema version in the database. #{error}"
log.error("Error: #{errorMessage}")
# Error: Could not initialise Pulse.
responseObject =
id: id
response:
error: true
errorMessage: "Could not initialise Pulse."
responseObject =
id: id
response:
error: true
errorMessage: errorMessage
@ws.send(JSON.stringify(responseObject), {binary: true})
return false
@ws.send(JSON.stringify(responseObject), {binary: true})
return false
makeWaystoneAccount: (id, accountHandle, deviceID, invitationCode) =>
......
......@@ -22,14 +22,15 @@
#
################################################################################
fs = require 'fs-extra'
path = require 'path-extra'
exec = require('child_process').exec
Promise = require 'bluebird'
Promise = require 'thrush'
winston = require 'winston'
isProcessRunning = require 'is-running'
fs = require 'fs-extra-as-promised'
Pulse = require 'pulse-node'
PulseProcess = Pulse.Process
PulseConfig = Pulse.Config
......@@ -53,6 +54,16 @@ Function::property = (prop, desc) ->
Object.defineProperty @prototype, prop, desc
# fs.exists cannot be automatically promisified
fs.existsAsync = (filePath)->
return new Promise ((fulfill, reject) ->
exists = fs.existsSync(filePath)
process.nextTick(->
fulfill(exists)
)
)
class Main
instance = null
......@@ -126,11 +137,21 @@ class Main
@createConfiguration()
#
# Run database migrations.
# Run database migrations (if we are already set up).
#
(new Migrations @config).runMigrations().then =>
fs.existsAsync @config.databaseFolder
.then (exists) =>
if exists
fs.existsAsync @config.syncFolder
.then (exists) =>
if exists
(new Migrations @config).runMigrations()
else
console.log 'ℹ️ Heartbeat not set up yet (could not find sync folder). Skipping migrations.'
else
console.log 'ℹ️ Heartbeat not set up yet (could not find database folder). Skipping migrations.'
.then =>
#
# Start the services.
#
......@@ -277,7 +298,7 @@ class Main
# Starts Node Socket with ourselves as the delegate.
#
startNodeSocket: =>
@nodeSocket = new NodeSocket delegate = this, debug = @debug, waystoneURL = @waystoneURL, invitationsURL = @invitationsURL, pulseAPI = @pulseAPI
@nodeSocket = new NodeSocket delegate = this, debug = @debug, waystoneURL = @waystoneURL, invitationsURL = @invitationsURL, pulseAPI = @pulseAPI, config = @config
#
......
......@@ -24,7 +24,7 @@
Promise = require 'thrush'
WriteStream = require 'write-stream'
path = require 'path-extra'
fs = Promise.promisifyAll(require 'fs-extra')
fs = require 'fs-extra-as-promised'
targz = require 'tar.gz'
walk = require './walk'
......
......@@ -5,7 +5,7 @@
#
# Controls the communication between the Node app and the native app.
#
Promise = require 'bluebird'
Promise = require 'thrush'
WebSocketServer = (require 'ws').Server
Commands = require './Commands'
......@@ -20,18 +20,20 @@ class NodeSocket
debug: false
waystoneURL: null
invitationsURL: null
config:null
constructor: (delegate, debug, waystoneURL, invitationsURL, pulseAPI) ->
constructor: (delegate, debug, waystoneURL, invitationsURL, pulseAPI, config) ->
@delegate = delegate
@debug = debug
@waystoneURL = waystoneURL
@invitationsURL = invitationsURL
@config = config
#
# Initialise the commands.
#
@commands = new Commands this, pulseAPI, debug, waystoneURL, invitationsURL
@commands = new Commands this, pulseAPI, debug, waystoneURL, invitationsURL, config
#
# Set up the web socket server.
......
......@@ -29,7 +29,7 @@ bodyParser = require('body-parser')
set = require 'indie-set'
path = require 'path-extra'
fs = require 'fs-extra'
fs = require 'fs-extra-as-promised'
mdns = require 'mdns'
StreamWeaver = require './StreamWeaver'
......
......@@ -9,11 +9,10 @@
"author": "Aral Balkan",
"license": "None yet, see LICENSE file for copyright information",
"dependencies": {
"bluebird": "2.3.2",
"body-parser": "1.6.5",
"coffee-script": "1.8.0",
"express": "4.8.3",
"fs-extra": "0.11.0",
"fs-extra-as-promised": "2.0.0",
"is-running": "1.0.5",
"level-live-stream": "1.4.9",
"level-manifest": "1.2.0",
......@@ -34,7 +33,7 @@
"superagent": "0.18.2",
"superagent-as-promised": "2.0.0",
"tar.gz": "1.0.0",
"thrush": "0.0.5",
"thrush": "0.0.7",
"winston": "1.0.0",
"write-stream": "0.4.3",
"ws": "https://github.com/aral/ws.git",
......
Promise = require 'bluebird'
Promise = require 'thrush'
superagent = require 'superagent'
path = require 'path-extra'
fs = Promise.promisifyAll(require 'fs-extra')
fs = require 'fs-extra-as-promised'
module.exports = (app) ->
......
Promise = require 'bluebird'
superagent = require 'superagent'
path = require 'path-extra'
fs = Promise.promisifyAll(require 'fs-extra')
fs = require 'fs-extra-as-promised'
module.exports = (app) ->
......
fs = require 'fs-extra'
fs = require 'fs-extra-as-promised'
path = require 'path-extra'
Promise = require 'thrush'
readdirAsync = Promise.promisify fs.readdir
statAsync = Promise.promisify fs.stat
#
# Based on http://stackoverflow.com/a/28130661 by Phil Mander
#
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment