Created
July 30, 2020 17:44
-
-
Save gilrosenthal/4bbef0594850f7bc93d61ea997b157ef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const router = express.Router() | |
const compute = require('compute-rhino3d') | |
const {performance} = require('perf_hooks') | |
const NodeCache = require('node-cache') | |
const cache = new NodeCache() | |
function computeParams (req, res, next){ | |
compute.url = req.app.get('computeUrl') | |
compute.authToken = process.env.COMPUTE_TOKEN | |
compute.apiKey = process.env.RHINO_COMPUTE_KEY | |
compute.apiToken = process.env.RHINO_API_TOKEN | |
next() | |
} | |
/** | |
* Solve GH definition | |
* This is the core "workhorse" function for the appserver. Client apps post | |
* json data to the appserver at this endpoint and that json is passed on to | |
* compute for solving with Grasshopper. | |
*/ | |
router.post('/', computeParams, function(req, res, next) { | |
const timePostStart = performance.now() | |
// ?? Do we need an option to skip caching | |
// Assume the same input will always result in the same output. | |
// In this case, we can cache the answer when the same question is asked. | |
// The current implementation uses a simple in-memory cache. Other | |
// solutions may want to use something like memcached, redis, or a database | |
const cacheKey = JSON.stringify(req.body) | |
let cachedResult = cache.get(cacheKey) | |
if (cachedResult) { | |
const timespanPost = Math.round(performance.now() - timePostStart) | |
res.setHeader('Server-Timing', `cacheHit;dur=${timespanPost}`) | |
res.setHeader('Content-Type', 'application/json') | |
res.send(cachedResult) | |
return | |
} | |
console.log(req.app.get('definitions').find(o => o.name === req.body.definition), req.body.definition) | |
let definition = req.app.get('definitions').find(o => o.name === req.body.definition) | |
console.log('def', definition) | |
if(!definition) | |
throw new Error('Definition not found on server.') | |
// set parameters | |
let trees = [] | |
if(req.body.inputs !== undefined) { // handle no inputs | |
for (let [key, value] of Object.entries(req.body.inputs)) { | |
let param = new compute.Grasshopper.DataTree(key) | |
param.append([0], [value]) | |
trees.push(param) | |
} | |
} | |
// let fullUrl = req.protocol + '://' + req.get('host') | |
// let definitionPath = `${fullUrl}/definition/${definition.id}` | |
let definitionPath='http://rhino-compute-test.herokuapp.com/definition/c02397599ae7c90eaadc279693180947' | |
console.log(definitionPath) | |
const timePreComputeServerCall = performance.now() | |
let computeServerTiming = null | |
// call compute server | |
compute.Grasshopper.evaluateDefinition(definitionPath, trees, false) | |
.then(computeResponse => { | |
computeServerTiming = computeResponse.headers | |
computeResponse.text().then(result=> { | |
console.log(computeResponse) | |
const timeComputeServerCallComplete = performance.now() | |
let computeTimings = computeServerTiming.get('server-timing') | |
let sum = 0 | |
computeTimings.split(',').forEach(element => { | |
let t = element.split('=')[1].trim() | |
sum += Number(t) | |
}) | |
const timespanCompute = timeComputeServerCallComplete - timePreComputeServerCall | |
const timespanComputeNetwork = Math.round(timespanCompute - sum) | |
const timespanSetup = Math.round(timePreComputeServerCall - timePostStart) | |
const timing = `setup;dur=${timespanSetup}, ${computeTimings}, network;dur=${timespanComputeNetwork}` | |
cache.set(cacheKey, result) | |
res.setHeader('Server-Timing', timing) | |
res.setHeader('Content-Type', 'application/json') | |
res.send(result) | |
}).catch( (error) => { | |
console.log(error) | |
res.send('error in solve') | |
}) | |
}) | |
}) | |
module.exports = router |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment