From def22a7b3fb7f360e47c930d4302f2ba7b6ce849 Mon Sep 17 00:00:00 2001
From: Daniel <nieltansah@gmail.com>
Date: Thu, 23 Nov 2017 23:07:33 +0700
Subject: [PATCH] app: Add improvements on chat service

Notes:
- Change API routes
- Simplify hub service
---
 app/api/chat.js    |  19 +++-----
 app/api/driver.js  |  46 +++++++++++---------
 app/api/index.js   |  10 +++--
 app/service/hub.js | 105 ++++++++++++++-------------------------------
 4 files changed, 72 insertions(+), 108 deletions(-)

diff --git a/app/api/chat.js b/app/api/chat.js
index 7ad3684..9c623cf 100644
--- a/app/api/chat.js
+++ b/app/api/chat.js
@@ -13,41 +13,36 @@ let app = express.Router()
 
 // Administration.
 
-app.post('/:id/token', function (req, res) {
+app.post('/init', function (req, res) {
   let id = req.params.id
   let token = req.body.token
 
   cloud.register(id, token)
 
-  res.json({ status: 'ok' })
+  res.json({})
 })
 
-app.delete('/:id', function (req, res) {
+app.delete('/', function (req, res) {
   let id = req.params.id
 
   cloud.unregister(id)
   relay.disassociate(id)
 
-  res.json({ status: 'ok' })
+  res.json({})
 })
 
 // Messaging.
 
-app.post('/:id/message', async function (req, res) {
+app.post('/', async function (req, res, next) {
   let id = req.params.id
   let message = req.body.message
 
   try {
     await relay.sendAsync(id, message)
 
-    res.json({ status: 'ok' })
+    res.json({})
   } catch (e) {
-    console.log(e)
-
-    res.json({
-      status: 'error',
-      message: e.message
-    })
+    next(e)
   }
 })
 
diff --git a/app/api/driver.js b/app/api/driver.js
index 2fc73aa..473f315 100644
--- a/app/api/driver.js
+++ b/app/api/driver.js
@@ -6,25 +6,22 @@
 
 const express = require('express')
 
+const chat = require('./chat')
 const hub = require('../service/hub')
 const relay = require('../service/relay')
 
 let app = express.Router()
 
-app.get('/find', function (req, res) {
-  let location = req.query.location
+// Mount chat controller.
+app.use('/chat', chat)
 
-  res.json({
-    'driver_ids': hub.filter(location)
-  })
-})
+// Administrations.
 
-app.post('/', async function (req, res) {
-  let id = req.body.driver_id
-  let locations = req.body.locations
+app.post('/wait', async function (req, res, next) {
+  let id = req.params.id
 
   try {
-    let userId = await hub.waitAsync(id, locations, function (reject) {
+    let userId = await hub.waitAsync(id, function (reject) {
       req.connection.on('close', () => reject(new Error('Aborted')))
     })
 
@@ -32,25 +29,32 @@ app.post('/', async function (req, res) {
       'user_id': userId
     })
   } catch (e) {
-    console.log(e)
+    next(e)
   }
 })
 
 app.post('/pick', function (req, res) {
-  let driverId = req.body.driver_id
+  let id = req.params.id
   let userId = req.body.user_id
 
-  try {
-    // Pick driver by user.
-    hub.pick(driverId, userId)
+  // Pick driver by user.
+  hub.pick(id, userId)
 
-    // Associate user with driver.
-    relay.associate(userId, driverId)
+  // Associate user with driver.
+  relay.associate(userId, id)
 
-    res.json({ 'status': 'ok' })
-  } catch (e) {
-    res.status(500).json({ 'status': 'error' })
-  }
+  res.json({})
+})
+
+// Queries.
+
+app.get('/', function (req, res) {
+  let id = req.params.id
+
+  // Check if driver exists.
+  hub.check(id)
+
+  res.json({})
 })
 
 module.exports = app
diff --git a/app/api/index.js b/app/api/index.js
index 1c65080..3cfb0c8 100644
--- a/app/api/index.js
+++ b/app/api/index.js
@@ -8,7 +8,6 @@ const cors = require('cors')
 const express = require('express')
 const bodyParser = require('body-parser')
 
-const chat = require('./chat')
 const driver = require('./driver')
 
 let app = express.Router()
@@ -16,7 +15,12 @@ let app = express.Router()
 app.use(cors())
 app.use(bodyParser.json())
 
-app.use('/chat', chat)
-app.use('/driver', driver)
+app.use('/driver/:id', driver)
+
+app.use(function (err, req, res, next) {
+  res.status(500).json({
+    error: err.message
+  })
+})
 
 module.exports = app
diff --git a/app/service/hub.js b/app/service/hub.js
index 0a90074..d714a6c 100644
--- a/app/service/hub.js
+++ b/app/service/hub.js
@@ -4,93 +4,54 @@
 
 'use strict'
 
-// Utilities.
-
-let index = function (id, locations) {
-  for (let location of locations) {
-    let ids = this.locations[location]
-
-    if (!ids) {
-      ids = new Set()
-      this.locations[location] = ids
-    }
-
-    ids.add(id)
-  }
-}
+let drivers = {}
+
+module.exports = {
+  async waitAsync (id, rejectFunc) {
+    let promise = new Promise((resolve, reject) => {
+      drivers[id] = {
+        resolve: resolve,
+        reject: reject
+      }
 
-let unindex = function (id, locations) {
-  for (let location of locations) {
-    let ids = this.locations[location]
+      // Pass reject function.
+      if (rejectFunc) {
+        rejectFunc(reject)
+      }
+    })
 
-    if (ids) {
-      ids.delete(id)
+    try {
+      return await promise
+    } finally {
+      delete drivers[id]
     }
-  }
-}
-
-// Main routine.
+  },
 
-class Hub {
-  constructor () {
-    this.drivers = {}
-    this.locations = {}
+  check (id) {
+    let handle = drivers[id]
 
-    let indexLambda = index.bind(this)
-    let unindexLambda = unindex.bind(this)
-
-    this.waitAsync = async (id, locations, rejectFunc) => {
-      let promise = new Promise((resolve, reject) => {
-        this.drivers[id] = {
-          resolve: resolve,
-          reject: reject
-        }
-
-        // Pass reject function.
-        if (rejectFunc) {
-          rejectFunc(reject)
-        }
-
-        // Index locations.
-        indexLambda(id, locations)
-      })
-
-      try {
-        return await promise
-      } finally {
-        // Remove indexed locations.
-        unindexLambda(id, locations)
-
-        delete this.drivers[id]
-      }
+    if (!handle) {
+      throw new Error(`Driver ID ${id} is not connected`)
     }
-  }
-
-  filter (location) {
-    return [...this.locations[location] || []]
-  }
+  },
 
   pick (id, userId) {
-    let handle = this.drivers[id]
+    let handle = drivers[id]
 
-    if (handle) {
-      handle.resolve(userId)
-      return true
+    if (!handle) {
+      throw new Error(`Driver ID ${id} is not connected`)
     }
 
-    return false
-  }
+    handle.resolve(userId)
+  },
 
   reject (id, reason) {
-    let handle = this.drivers[id]
+    let handle = drivers[id]
 
-    if (handle) {
-      handle.reject(reason)
-      return true
+    if (!handle) {
+      throw new Error(`Driver ID ${id} is not connected`)
     }
 
-    return false
+    handle.reject(reason)
   }
 }
-
-module.exports = new Hub()
-- 
GitLab