@@ -187,7 +187,7 @@ func (s *Server) checkPossibleModulePaths(ctx context.Context, db *postgres.DB,
187
187
// Before enqueuing the module version to be fetched, check if we
188
188
// have already attempted to fetch it in the past. If so, just
189
189
// return the result from that fetch process.
190
- fr := checkForPath (ctx , db , fullPath , modulePath , requestedVersion )
190
+ fr := checkForPath (ctx , db , fullPath , modulePath , requestedVersion , s . taskIDChangeInterval )
191
191
if ! shouldQueue || fr .status != statusNotFoundInVersionMap {
192
192
results [i ] = fr
193
193
return
@@ -200,7 +200,7 @@ func (s *Server) checkPossibleModulePaths(ctx context.Context, db *postgres.DB,
200
200
}
201
201
// After the fetch request is enqueued, poll the database until it has been
202
202
// inserted or the request times out.
203
- fr = pollForPath (ctx , db , pollEvery , fullPath , modulePath , requestedVersion )
203
+ fr = pollForPath (ctx , db , pollEvery , fullPath , modulePath , requestedVersion , s . taskIDChangeInterval )
204
204
logf := log .Infof
205
205
if fr .status == http .StatusInternalServerError {
206
206
logf = log .Errorf
@@ -270,7 +270,7 @@ func displayPath(path, version string) string {
270
270
271
271
// pollForPath polls the database until a row for fullPath is found.
272
272
func pollForPath (ctx context.Context , db * postgres.DB , pollEvery time.Duration ,
273
- fullPath , modulePath , requestedVersion string ) * fetchResult {
273
+ fullPath , modulePath , requestedVersion string , taskIDChangeInterval time. Duration ) * fetchResult {
274
274
fr := & fetchResult {modulePath : modulePath }
275
275
defer derrors .Wrap (& fr .err , "pollForRedirectURL(%q, %q, %q)" , modulePath , fullPath , requestedVersion )
276
276
ticker := time .NewTicker (pollEvery )
@@ -285,7 +285,7 @@ func pollForPath(ctx context.Context, db *postgres.DB, pollEvery time.Duration,
285
285
case <- ticker .C :
286
286
ctx2 , cancel := context .WithTimeout (ctx , pollEvery )
287
287
defer cancel ()
288
- fr = checkForPath (ctx2 , db , fullPath , modulePath , requestedVersion )
288
+ fr = checkForPath (ctx2 , db , fullPath , modulePath , requestedVersion , taskIDChangeInterval )
289
289
if fr .status != statusNotFoundInVersionMap {
290
290
return fr
291
291
}
@@ -299,7 +299,8 @@ func pollForPath(ctx context.Context, db *postgres.DB, pollEvery time.Duration,
299
299
// process that was initiated is not yet complete. If the row exists version_map
300
300
// but not paths, it means that a module was found at the requestedVersion, but
301
301
// not the fullPath, so errPathDoesNotExistInModule is returned.
302
- func checkForPath (ctx context.Context , db * postgres.DB , fullPath , modulePath , requestedVersion string ) (fr * fetchResult ) {
302
+ func checkForPath (ctx context.Context , db * postgres.DB ,
303
+ fullPath , modulePath , requestedVersion string , taskIDChangeInterval time.Duration ) (fr * fetchResult ) {
303
304
defer func () {
304
305
// Based on
305
306
// https://github.com/lib/pq/issues/577#issuecomment-298341053, it seems
@@ -344,7 +345,26 @@ func checkForPath(ctx context.Context, db *postgres.DB, fullPath, modulePath, re
344
345
goModPath : vm .GoModPath ,
345
346
}
346
347
switch fr .status {
347
- case http .StatusNotFound :
348
+ case http .StatusNotFound ,
349
+ derrors .ToStatus (derrors .DBModuleInsertInvalid ),
350
+ http .StatusInternalServerError :
351
+ if time .Since (vm .UpdatedAt ) > taskIDChangeInterval {
352
+ // If the duration of taskIDChangeInterval has passed since
353
+ // a module_path was last inserted into version_map with a failed status,
354
+ // treat that data as expired.
355
+ //
356
+ // It is possible that the module has appeared in the Go Module
357
+ // Mirror during that time, the failure was transient, or the
358
+ // error has been fixed but the module version has not yet been
359
+ // reprocessed.
360
+ //
361
+ // Return statusNotFoundInVersionMap here, so that the fetch
362
+ // request will try to fetch this module version again.
363
+ // Since the taskIDChangeInterval has passed, it is now possible to
364
+ // enqueue that module version to the frontend task queue again.
365
+ fr .status = statusNotFoundInVersionMap
366
+ return fr
367
+ }
348
368
// The version_map indicates that the proxy returned a 404/410.
349
369
fr .err = errModuleDoesNotExist
350
370
return fr
0 commit comments