22 * FunctionDiscovery — lazy, cached lookups against the
33 * platform function definitions table.
44 *
5- * Schema and table names are resolved dynamically via ComputeModuleLoader
6- * instead of hardcoding a specific schema. When a job arrives the worker
7- * calls `resolve(taskIdentifier)`. On cache miss, a single SQL query
8- * fetches the function definition and caches it for `ttlMs` (default 60 s).
5+ * Schema and table names are resolved dynamically via ModuleLoader.
96 */
107
11- import { TtlCache } from '@constructive-io/module-loader' ;
12- import type { ComputeModuleLoader } from '@constructive-io/module-loader' ;
8+ import { ModuleLoader } from '@constructive-io/module-loader' ;
139import { Logger } from '@pgpmjs/logger' ;
1410import type { Pool } from 'pg' ;
1511
12+ import { TtlCache } from './cache' ;
1613import type { PlatformFunctionDefinition } from './types' ;
1714
1815const log = new Logger ( 'compute:discovery' ) ;
@@ -27,75 +24,47 @@ const COLUMNS = `
2724export class FunctionDiscovery {
2825 private cache : TtlCache < PlatformFunctionDefinition | null > ;
2926 private pool : Pool ;
30- private loader : ComputeModuleLoader ;
27+ private loader : ModuleLoader ;
3128 private databaseId : string ;
3229
33- constructor ( pool : Pool , loader : ComputeModuleLoader , databaseId : string , ttlMs = 60_000 ) {
30+ constructor ( pool : Pool , loader : ModuleLoader , databaseId : string , ttlMs = 60_000 ) {
3431 this . pool = pool ;
3532 this . loader = loader ;
3633 this . databaseId = databaseId ;
3734 this . cache = new TtlCache < PlatformFunctionDefinition | null > ( ttlMs ) ;
3835 }
3936
40- /**
41- * Lazily resolve a function definition by task_identifier.
42- * Returns null if not registered. Results are TTL-cached.
43- */
4437 async resolve ( taskIdentifier : string ) : Promise < PlatformFunctionDefinition | null > {
4538 const cached = this . cache . get ( taskIdentifier ) ;
46- if ( cached !== undefined ) {
47- log . debug ( `cache hit: ${ taskIdentifier } ` ) ;
48- return cached ;
49- }
39+ if ( cached !== undefined ) return cached ;
5040
51- log . debug ( `cache miss: ${ taskIdentifier } , querying DB` ) ;
5241 try {
53- const config = await this . loader . load ( this . databaseId ) ;
54- const publicSchema = config . functionModule ?. publicSchema ?? 'constructive_compute_public' ;
55- const definitionsTable = config . functionModule ?. definitionsTable ?? 'platform_function_definitions' ;
56- const sql = `SELECT ${ COLUMNS } FROM "${ publicSchema } "."${ definitionsTable } " WHERE task_identifier = $1 LIMIT 1` ;
57-
42+ const cfg = await this . loader . function . load ( this . databaseId , null ) ;
43+ const sql = `SELECT ${ COLUMNS } FROM "${ cfg . publicSchema } "."${ cfg . definitionsTable } " WHERE task_identifier = $1 LIMIT 1` ;
5844 const { rows } = await this . pool . query ( sql , [ taskIdentifier ] ) ;
5945 const def = ( rows [ 0 ] as PlatformFunctionDefinition ) ?? null ;
6046 this . cache . set ( taskIdentifier , def ) ;
61- if ( def ) {
62- log . info ( `resolved function: ${ def . name } (${ taskIdentifier } ) → ${ def . service_url ?? 'no url' } ` ) ;
63- } else {
64- log . warn ( `no function registered for task_identifier="${ taskIdentifier } "` ) ;
65- }
6647 return def ;
67- } catch ( err : any ) {
68- log . error ( `failed to resolve "${ taskIdentifier } ": ${ err . message } ` ) ;
48+ } catch ( err : unknown ) {
49+ const msg = err instanceof Error ? err . message : String ( err ) ;
50+ log . error ( `failed to resolve "${ taskIdentifier } ": ${ msg } ` ) ;
6951 return null ;
7052 }
7153 }
7254
73- /**
74- * List all invocable function definitions.
75- * Not cached — intended for startup diagnostics / admin endpoints.
76- */
7755 async listInvocable ( ) : Promise < PlatformFunctionDefinition [ ] > {
7856 try {
79- const config = await this . loader . load ( this . databaseId ) ;
80- const publicSchema = config . functionModule ?. publicSchema ?? 'constructive_compute_public' ;
81- const definitionsTable = config . functionModule ?. definitionsTable ?? 'platform_function_definitions' ;
82- const sql = `SELECT ${ COLUMNS } FROM "${ publicSchema } "."${ definitionsTable } " WHERE is_invocable = true ORDER BY name` ;
83-
57+ const cfg = await this . loader . function . load ( this . databaseId , null ) ;
58+ const sql = `SELECT ${ COLUMNS } FROM "${ cfg . publicSchema } "."${ cfg . definitionsTable } " WHERE is_invocable = true ORDER BY name` ;
8459 const { rows } = await this . pool . query ( sql ) ;
8560 return rows as PlatformFunctionDefinition [ ] ;
86- } catch ( err : any ) {
87- log . error ( `failed to list invocable functions: ${ err . message } ` ) ;
61+ } catch ( err : unknown ) {
62+ const msg = err instanceof Error ? err . message : String ( err ) ;
63+ log . error ( `failed to list invocable functions: ${ msg } ` ) ;
8864 return [ ] ;
8965 }
9066 }
9167
92- /** Invalidate cached entry for a specific task. */
93- invalidate ( taskIdentifier : string ) : void {
94- this . cache . delete ( taskIdentifier ) ;
95- }
96-
97- /** Clear the entire cache. */
98- invalidateAll ( ) : void {
99- this . cache . clear ( ) ;
100- }
68+ invalidate ( taskIdentifier : string ) : void { this . cache . delete ( taskIdentifier ) ; }
69+ invalidateAll ( ) : void { this . cache . clear ( ) ; }
10170}
0 commit comments