import { reuseInFlight } from "async-await-utils/hof" ; import { getProject } from "@cocalc/server/projects/control" ; import getLogger from "@cocalc/backend/logger" ; import { callback2 } from "@cocalc/util/async-utils" ; import initialize from "./initialize" ; import { cancelAll } from "./handle-query" ; const { connect_to_locked_socket } = require ( "@cocalc/backend/misc_node" ) ; const logger = getLogger ( "project-connection:connect" ) ; type Connection = any ; 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 = getProject ( project_id ) ; dbg ( "getting address of " , project_id ) ; const { host , port , secret_token : token } = await project . address ( ) ; dbg ( "got " , host , port ) ; const socket = await callback2 ( connect_to_locked_socket , { host , port , token , } ) ; initialize ( project_id , socket ) ; function free ( ) { for ( const evt of EndEvents ) { socket . removeListener ( evt , free ) ; } delete CACHE [ project_id ] ; try { socket . end ( ) ; } catch ( _ ) { } cancelAll ( project_id ) ; } for ( const evt of EndEvents ) { socket . on ( evt , free ) ; } CACHE [ project_id ] = socket ; return socket ; } const getConnection = reuseInFlight ( connect ) ; export default getConnection ;