@@ -19,6 +19,7 @@ import {
19
19
WorkspaceAndInstance ,
20
20
WorkspaceInfo ,
21
21
WorkspaceInstance ,
22
+ WorkspaceInstanceMetrics ,
22
23
WorkspaceInstanceUser ,
23
24
WorkspaceSession ,
24
25
WorkspaceType ,
@@ -62,6 +63,7 @@ import { TypeORM } from "./typeorm";
62
63
import { ApplicationError , ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error" ;
63
64
import { DBProject } from "./entity/db-project" ;
64
65
import { PrebuiltWorkspaceWithWorkspace } from "@gitpod/gitpod-protocol/src/protocol" ;
66
+ import { DBWorkspaceInstanceMetrics } from "./entity/db-workspace-instance-metrics" ;
65
67
66
68
type RawTo < T > = ( instance : WorkspaceInstance , ws : Workspace ) => T ;
67
69
interface OrderBy {
@@ -109,6 +111,10 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl<WorkspaceDB> imp
109
111
) ;
110
112
}
111
113
114
+ private async getWorkspaceInstanceMetricsRepo ( ) : Promise < Repository < DBWorkspaceInstanceMetrics > > {
115
+ return ( await this . getEntityManager ( ) ) . getRepository < DBWorkspaceInstanceMetrics > ( DBWorkspaceInstanceMetrics ) ;
116
+ }
117
+
112
118
public async connect ( maxTries : number = 3 , timeout : number = 2000 ) : Promise < void > {
113
119
let tries = 1 ;
114
120
while ( tries <= maxTries ) {
@@ -459,27 +465,39 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl<WorkspaceDB> imp
459
465
offset : number ,
460
466
) : Promise < WorkspaceSession [ ] > {
461
467
const workspaceInstanceRepo = await this . getWorkspaceInstanceRepo ( ) ;
468
+
462
469
// The query basically selects all workspace instances for the given owner, whose startDate is within the period, and which are either:
463
470
// - not stopped yet, or
464
471
// - is stopped or stopping.
465
- const sessions = await workspaceInstanceRepo
472
+ type JoinResult = DBWorkspaceInstance & {
473
+ metrics : DBWorkspaceInstanceMetrics | undefined ;
474
+ workspace : DBWorkspace ;
475
+ } ;
476
+ const sessions = ( await workspaceInstanceRepo
466
477
. createQueryBuilder ( "wsi" )
467
478
. leftJoinAndMapOne ( "wsi.workspace" , DBWorkspace , "ws" , "ws.id = wsi.workspaceId" )
479
+ . leftJoinAndMapOne ( "wsi.metrics" , DBWorkspaceInstanceMetrics , "wsim" , "wsim.instanceId = wsi.id" )
468
480
. where ( "ws.organizationId = :organizationId" , { organizationId } )
469
481
. andWhere ( "wsi.creationTime >= :periodStart" , { periodStart : periodStart . toISOString ( ) } )
470
482
. andWhere ( "wsi.creationTime <= :periodEnd" , { periodEnd : periodEnd . toISOString ( ) } )
471
483
. orderBy ( "wsi.creationTime" , "DESC" )
472
484
. skip ( offset )
473
485
. take ( limit )
474
- . getMany ( ) ;
486
+ . getMany ( ) ) as JoinResult [ ] ;
475
487
476
- const resultSessions : { instance : WorkspaceInstance ; workspace : Workspace } [ ] = [ ] ;
488
+ const resultSessions : {
489
+ instance : WorkspaceInstance ;
490
+ workspace : Workspace ;
491
+ metrics ?: WorkspaceInstanceMetrics ;
492
+ } [ ] = [ ] ;
477
493
for ( const session of sessions ) {
478
494
resultSessions . push ( {
479
- workspace : ( session as any ) . workspace ,
495
+ workspace : session . workspace ,
480
496
instance : session ,
497
+ metrics : session . metrics ?. metrics ,
481
498
} ) ;
482
499
delete ( session as any ) . workspace ;
500
+ delete ( session as any ) . metrics ;
483
501
}
484
502
return resultSessions ;
485
503
}
@@ -1143,6 +1161,36 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl<WorkspaceDB> imp
1143
1161
const res = await query . getMany ( ) ;
1144
1162
return res . map ( ( r ) => r . info ) ;
1145
1163
}
1164
+
1165
+ async storeMetrics ( instanceId : string , metrics : WorkspaceInstanceMetrics ) : Promise < WorkspaceInstanceMetrics > {
1166
+ const repo = await this . getWorkspaceInstanceMetricsRepo ( ) ;
1167
+ const result = await repo . save ( {
1168
+ instanceId,
1169
+ metrics,
1170
+ } ) ;
1171
+ return result . metrics ;
1172
+ }
1173
+
1174
+ async getMetrics ( instanceId : string ) : Promise < WorkspaceInstanceMetrics | undefined > {
1175
+ const repo = await this . getWorkspaceInstanceMetricsRepo ( ) ;
1176
+ const dbMetrics = await repo . findOne ( { where : { instanceId } } ) ;
1177
+ return dbMetrics ?. metrics ;
1178
+ }
1179
+
1180
+ async updateMetrics (
1181
+ instanceId : string ,
1182
+ update : WorkspaceInstanceMetrics ,
1183
+ merge : ( current : WorkspaceInstanceMetrics , update : WorkspaceInstanceMetrics ) => WorkspaceInstanceMetrics ,
1184
+ ) : Promise < WorkspaceInstanceMetrics > {
1185
+ return await this . transaction ( async ( db ) => {
1186
+ const current = await db . getMetrics ( instanceId ) ;
1187
+ if ( ! current ) {
1188
+ return await db . storeMetrics ( instanceId , update ) ;
1189
+ }
1190
+ const merged = merge ( current , update ) ;
1191
+ return await db . storeMetrics ( instanceId , merged ) ;
1192
+ } ) ;
1193
+ }
1146
1194
}
1147
1195
1148
1196
type InstanceJoinResult = DBWorkspace & { instance : WorkspaceInstance } ;
0 commit comments