@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
85 lines (83 loc) • 3.05 kB
JavaScript
;
/*
Create or return the TCP connection from this server to a given project.
The connection is cached and calling this is async debounced, so call it
all you want.
This will also try to start the project up to about a minute.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const hof_1 = require("async-await-utils/hof");
const control_1 = require("@cocalc/server/projects/control");
const logger_1 = __importDefault(require("@cocalc/backend/logger"));
const async_utils_1 = require("@cocalc/util/async-utils");
const initialize_1 = __importDefault(require("./initialize"));
const handle_query_1 = require("./handle-query");
const awaiting_1 = require("awaiting");
// misc_node is still in coffeescript :-(
//import { connect_to_locked_socket } from "@cocalc/backend/misc_node";
const { connect_to_locked_socket } = require("@cocalc/backend/misc_node");
const logger = (0, logger_1.default)("project-connection:connect");
const CACHE = {};
const EndEvents = ["end", "close", "error"];
async function connect(project_id) {
logger.info("connect to ", project_id);
const dbg = (...args) => logger.debug(project_id, ...args);
if (CACHE[project_id]) {
dbg("got ", project_id, " from cache");
return CACHE[project_id];
}
const project = (0, control_1.getProject)(project_id);
// Calling address starts the project running, then returns
// information about where it is running and how to connection.
// We retry a few times, in case project isn't running yet.
dbg("getting address of ", project_id);
let socket;
let i = 0;
while (true) {
try {
const { host, port, secret_token: token } = await project.address();
dbg("got ", host, port);
socket = await (0, async_utils_1.callback2)(connect_to_locked_socket, {
host,
port,
token,
});
break;
}
catch (err) {
dbg(err);
if (i >= 10) {
// give up!
throw err;
}
await project.start();
await (0, awaiting_1.delay)(1000 * i);
i += 1;
}
}
(0, initialize_1.default)(project_id, socket);
function free() {
logger.info("disconnect from ", project_id);
// don't want free to be triggered more than once.
for (const evt of EndEvents) {
socket.removeListener(evt, free);
}
delete CACHE[project_id];
try {
socket.end();
}
catch (_) { }
(0, handle_query_1.cancelAll)(project_id);
}
for (const evt of EndEvents) {
socket.on(evt, free);
}
CACHE[project_id] = socket;
return socket;
}
const getConnection = (0, hof_1.reuseInFlight)(connect);
exports.default = getConnection;
//# sourceMappingURL=connect.js.map