@@ -27,13 +27,11 @@ import (
2727)
2828
2929const (
30- maxSandboxListLimit int32 = 100
31- defaultSandboxListLimit int32 = 100
30+ sandboxesDefaultLimit = int32 ( 100 )
31+ sandboxesMaxLimit = int32 ( 100 )
3232)
3333
34- func (a * APIStore ) getPausedSandboxes (ctx context.Context , teamID uuid.UUID , runningSandboxesIDs []string , metadataFilter * map [string ]string , limit int32 , cursorTime time.Time , cursorID string ) ([]utils.PaginatedSandbox , error ) {
35- // Apply limit + 1 to check if there are more results
36- queryLimit := limit + 1
34+ func (a * APIStore ) getPausedSandboxes (ctx context.Context , teamID uuid.UUID , runningSandboxesIDs []string , metadataFilter * map [string ]string , queryLimit int32 , cursorTime time.Time , cursorID string ) ([]utils.PaginatedSandbox , error ) {
3735 queryMetadata := dbtypes.JSONBStringMap {}
3836 if metadataFilter != nil {
3937 queryMetadata = * metadataFilter
@@ -115,14 +113,23 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
115113 states = append (states , * params .State ... )
116114 }
117115
118- limit := defaultSandboxListLimit
119- if params .Limit != nil {
120- limit = * params .Limit
121- }
116+ // Initialize pagination
117+ pagination , err := utils .NewPagination [utils.PaginatedSandbox ](
118+ utils.PaginationParams {
119+ Limit : params .Limit ,
120+ NextToken : params .NextToken ,
121+ },
122+ utils.PaginationConfig {
123+ DefaultLimit : sandboxesDefaultLimit ,
124+ MaxLimit : sandboxesMaxLimit ,
125+ DefaultID : utils .MaxSandboxID ,
126+ },
127+ )
128+ if err != nil {
129+ telemetry .ReportError (ctx , "error parsing pagination cursor" , err )
130+ a .sendAPIStoreError (c , http .StatusBadRequest , "Invalid next token" )
122131
123- // Clip limit to max
124- if limit > maxSandboxListLimit {
125- limit = maxSandboxListLimit
132+ return
126133 }
127134
128135 metadataFilter , err := utils .ParseMetadata (params .Metadata )
@@ -136,15 +143,6 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
136143 // Get sandboxes with pagination
137144 sandboxes := make ([]utils.PaginatedSandbox , 0 )
138145
139- // Parse the next token to offset sandboxes for pagination
140- cursorTime , cursorID , err := utils .ParseNextToken (params .NextToken )
141- if err != nil {
142- zap .L ().Error ("Error parsing cursor" , zap .Error (err ))
143- a .sendAPIStoreError (c , http .StatusBadRequest , "Invalid next token" )
144-
145- return
146- }
147-
148146 allSandboxes := a .orchestrator .GetSandboxes (ctx , team .ID , []sandbox.State {sandbox .StateRunning , sandbox .StatePausing })
149147 runningSandboxes := sharedUtils .Filter (allSandboxes , func (sbx sandbox.Sandbox ) bool {
150148 return sbx .State == sandbox .StateRunning
@@ -163,7 +161,7 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
163161 c .Header ("X-Total-Running" , strconv .Itoa (len (runningSandboxList )))
164162
165163 // Filter based on cursor
166- runningSandboxList = utils .FilterBasedOnCursor (runningSandboxList , cursorTime , cursorID )
164+ runningSandboxList = utils .FilterBasedOnCursor (runningSandboxList , pagination . CursorTime (), pagination . CursorID () )
167165
168166 sandboxes = append (sandboxes , runningSandboxList ... )
169167 }
@@ -178,7 +176,7 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
178176 runningSandboxesIDs = append (runningSandboxesIDs , utils .ShortID (info .SandboxID ))
179177 }
180178
181- pausedSandboxList , err := a .getPausedSandboxes (ctx , team .ID , runningSandboxesIDs , metadataFilter , limit , cursorTime , cursorID )
179+ pausedSandboxList , err := a .getPausedSandboxes (ctx , team .ID , runningSandboxesIDs , metadataFilter , pagination . QueryLimit (), pagination . CursorTime (), pagination . CursorID () )
182180 if err != nil {
183181 zap .L ().Error ("Error getting paused sandboxes" , zap .Error (err ))
184182 a .sendAPIStoreError (c , http .StatusInternalServerError , "Error getting paused sandboxes" )
@@ -188,7 +186,7 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
188186
189187 pausingSandboxList := instanceInfoToPaginatedSandboxes (pausingSandboxes )
190188 pausingSandboxList = utils .FilterSandboxesOnMetadata (pausingSandboxList , metadataFilter )
191- pausingSandboxList = utils .FilterBasedOnCursor (pausingSandboxList , cursorTime , cursorID )
189+ pausingSandboxList = utils .FilterBasedOnCursor (pausingSandboxList , pagination . CursorTime (), pagination . CursorID () )
192190
193191 sandboxes = append (sandboxes , pausedSandboxList ... )
194192 sandboxes = append (sandboxes , pausingSandboxList ... )
@@ -197,21 +195,9 @@ func (a *APIStore) GetV2Sandboxes(c *gin.Context, params api.GetV2SandboxesParam
197195 // We need to sort again after merging running and paused sandboxes
198196 utils .SortPaginatedSandboxesDesc (sandboxes )
199197
200- var nextToken * string
201- if len (sandboxes ) > int (limit ) {
202- // We have more results than the limit, so we need to set the nextToken
203- lastSandbox := sandboxes [limit - 1 ]
204- cursor := lastSandbox .GenerateCursor ()
205- nextToken = & cursor
206-
207- // Trim to the requested limit
208- sandboxes = sandboxes [:limit ]
209- }
210-
211- // Add pagination info to headers
212- if nextToken != nil {
213- c .Header ("X-Next-Token" , * nextToken )
214- }
198+ sandboxes = pagination .ProcessResultsWithHeader (c , sandboxes , func (s utils.PaginatedSandbox ) (time.Time , string ) {
199+ return s .PaginationTimestamp , s .SandboxID
200+ })
215201
216202 c .JSON (http .StatusOK , sandboxes )
217203}
0 commit comments