@buerli.io/nodedeprecated

node.js classcad instance manager

Usage no npm install needed!

<script type="module">
  import buerliIoNode from 'https://cdn.skypack.dev/@buerli.io/node';
</script>

README

ClassCAD instance manager based on Node.js

This is a Node.js implementation using Socket.IO as the communications protocol.

Install

npm install @buerli.io/node

Instance server

The instance manager represents a single endpoint where users connect in order to work with ClassCAD sessions. It may ship ClassCAD binaries and boot them up when starting, but it can also rely on seperate 'farms', servers that host ClassCAD processes.

const path = require('path')
const Server = require('@buerli.io/node/server').default
const Logger = require('@buerli.io/node/extras/logger').default

const server = new Server(
  {
    instances: 1,
    // The following are all defaults ...
    executable: 'ClassCADInstance.exe',
    configurationData: 'CADApplication.ini',
    output: path.resolve('./node_modules/@awv/classcad_cadapplication'),
    protocol: 'http',
    serverOptions: {},
    ip: 'localhost',
    privatePort: 0,
    publicPort: 8181,
    binary: true,
    multipart: true,
    compression: true,
    sendTreePatches: true,
    stdout: false,
    secureApi: false,
    debug: true,
    showConsole: false,
    stateDebounce: 500,
    workerTimeout: 1000 * 15,
    restTimeout: 1000 * 60 * 2,
    collectResultsOnly: true,
    logExpirationDays: 5,
  },
  Logger({ spinOnFirstUser: true }),
).start()

REST API

Log in a new user with the /login endpoint. The user will be treated in the same way as a socket.IO user. This has been abstracted in the awv3 library under the /communication/rest class which features the same API as the socketio or the signalr classes.

GET /login/:id

    response => { op: 'system', status: [either 'permitted' or 'rejected'], id: [session ID] }

Log out with the /logout endpoint

GET /logout/:id

    response => "disconnected"

Execute tasks with the /execute endpoint. Note that due to the limitations of REST, there is no server push available. Results will be sent in a single, complete chunk. Another limitation is that requests may time out, should the server be too busy. Such errors need to be handled by the client.

POST /execute/:id
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    method: "POST",
    body: JSON.stringify(command)

    response => Array of results

Custom load balancing

Override the [server.health] function to determine the instances health status. The function must return a HTTP status code. Load balancers can probe the /health endpoint to flag single instances as busy, which will remove them from the set of balanced instances until they become active again. The default criteria seeks to flag an instance as not-healthy (status code 503, service unavailable) if 90% of its ClassCAD sessions are busy.

server.health = function() {
  let sessions = Array.from(server.sessions.values())
  let busy = 0
  for (let session of sessions) if (session.tasks.size > 0) busy++

  // If 90% are busy, start flagging the instance as unhealthy
  return busy > sessions.length * 0.9 ? 503 : 200
}