@@ -3,15 +3,18 @@ import { Dagula } from 'dagula'
3
3
import { CarReader } from '@ipld/car'
4
4
import { parseCid , HttpError , toIterable } from '@web3-storage/gateway-lib/util'
5
5
import { BatchingR2Blockstore } from './lib/blockstore.js'
6
+ import { MemoryBudget } from './lib/mem-budget.js'
6
7
7
8
const MAX_CAR_BYTES_IN_MEMORY = 1024 * 1024 * 5
8
9
const CAR_CODE = 0x0202
10
+ const MAX_MEMORY_BUDGET = 1024 * 1024 * 50
9
11
10
12
/**
11
13
* @typedef {import('./bindings').Environment } Environment
12
14
* @typedef {import('@web3-storage/gateway-lib').IpfsUrlContext } IpfsUrlContext
13
15
* @typedef {import('./bindings').CarCidsContext } CarCidsContext
14
16
* @typedef {import('@web3-storage/gateway-lib').DagulaContext } DagulaContext
17
+ * @typedef {import('./bindings').MemoryBudgetContext } MemoryBudgetContext
15
18
*/
16
19
17
20
/**
@@ -75,15 +78,50 @@ export function withCarCids (handler) {
75
78
}
76
79
}
77
80
81
+ /**
82
+ * @type {import('@web3-storage/gateway-lib').Middleware<MemoryBudgetContext> }
83
+ */
84
+ export function withMemoryBudget ( handler ) {
85
+ return async ( request , env , ctx ) => {
86
+ const memoryBudget = new MemoryBudget ( MAX_MEMORY_BUDGET )
87
+ return handler ( request , env , { ...ctx , memoryBudget } )
88
+ }
89
+ }
90
+
91
+ /**
92
+ * @type {import('@web3-storage/gateway-lib').Middleware<MemoryBudgetContext, MemoryBudgetContext> }
93
+ */
94
+ export function withResponseMemoryRelease ( handler ) {
95
+ return async ( request , env , ctx ) => {
96
+ const response = await handler ( request , env , ctx )
97
+
98
+ const body = response . body
99
+ if ( ! body ) return response
100
+
101
+ console . log ( 'adding response memory release transform...' )
102
+
103
+ return new Response (
104
+ body . pipeThrough ( new TransformStream ( {
105
+ transform ( chunk , controller ) {
106
+ ctx . memoryBudget . release ( chunk . length )
107
+ controller . enqueue ( chunk )
108
+ }
109
+ } ) ) ,
110
+ response
111
+ )
112
+ }
113
+ }
114
+
78
115
/**
79
116
* Creates a dagula instance backed by the R2 blockstore.
80
- * @type {import('@web3-storage/gateway-lib').Middleware<DagulaContext & CarCidsContext & IpfsUrlContext, CarCidsContext & IpfsUrlContext, Environment> }
117
+ * @type {import('@web3-storage/gateway-lib').Middleware<DagulaContext & MemoryBudgetContext & CarCidsContext & IpfsUrlContext, MemoryBudgetContext & CarCidsContext & IpfsUrlContext, Environment> }
81
118
*/
82
119
export function withDagula ( handler ) {
83
120
return async ( request , env , ctx ) => {
84
- const { carCids, searchParams } = ctx
121
+ const { carCids, searchParams, memoryBudget } = ctx
85
122
if ( ! carCids ) throw new Error ( 'missing CAR CIDs in context' )
86
123
if ( ! searchParams ) throw new Error ( 'missing URL search params in context' )
124
+ if ( ! memoryBudget ) throw new Error ( 'missing memory budget instance' )
87
125
88
126
/** @type {import('dagula').Blockstore? } */
89
127
let blockstore = null
@@ -99,7 +137,7 @@ export function withDagula (handler) {
99
137
}
100
138
101
139
if ( ! blockstore ) {
102
- blockstore = new BatchingR2Blockstore ( env . CARPARK , env . SATNAV , carCids )
140
+ blockstore = new BatchingR2Blockstore ( env . CARPARK , env . SATNAV , carCids , memoryBudget )
103
141
}
104
142
105
143
const dagula = new Dagula ( blockstore )
0 commit comments