ETag and Bytes discrepancy with a Put Block List replacing the same Block Blob
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- Medio día
- Aptitud para principiantes
- 62/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- nodejs, typescript
Línea de trabajo
Start in LokiBlobMetadataStore.downloadBlob, which returns the live LokiJS record, and compare it with commitBlockList, which updates that record in place; BlobHandler reads blob.properties.etag after awaiting the body stream. The proposed fix is to return a copy of the record, and the test to add is tests/blob/unit/lokiBlobMetadataStore.unit.test.ts (@loki). Done when the downloaded model keeps v1's ETag, content length and block list after a v2 commit, and the test passes.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
When a ranged Get Blob runs while a Put Block List is replacing the same Block Blob, Azurite can return the new ETag together with the old bytes. Discovered when testing the operations against the container, used via a git patch file against the docker image for now but have a PR up to solve this issue also.
Details
downloadBlob returns the live LokiJS record, because LokiJS doesn't copy records on read. BlobHandler reads the block list, then waits on the body stream and the range MD5, and only then reads blob.properties.etag. During that wait, commitBlockList updates the same record in place. The response then pairs the old bytes, and an MD5 of those bytes, with the new ETag.
Clients can't detect this:
If-Match on later ranges passes, because the first range already returned the new ETag.
Each range's MD5 matches its own bytes, so content validation passes.
A chunked read returns a mix of two versions: old bytes in the first range and new bytes after.
On upstream 3.37.0, about half of the reads that ran alongside a commit came back mixed (264 of 540), with 0 MD5 mismatches. Real Azure serves each read from one version.
Proposed fix
Only affects the Loki metadata store.
Make LokiBlobMetadataStore.downloadBlob return a copy of the record instead of the live LokiJS record:
return structuredClone(doc); // was return doc;
commitBlockList makes all its changes with no await in between. So a copy taken by downloadBlob always holds one complete version, old or new. The ETag, block list and content length in a response then always belong to the same version.
The callers (block, page and append blob handlers, and copy) only read the returned model and never write it back, so a copy works for all of them. structuredClone needs Node 17 or later, and engines already requires Node 22 or later.
Test
A new unit test, tests/blob/unit/lokiBlobMetadataStore.unit.test.ts (@loki), uses an in-memory Loki store:
- Commit v1 of a Block Blob.
- Call
downloadBlob. - Commit v2.
- Check that the downloaded model still has v1's ETag, content length and block list, and that a new
downloadBlobreturns v2.
Without the fix the test fails with 'etag-v2' !== 'etag-v1'.
- Lenguaje dominante
- TypeScript
- Estrellas
- 2.3k
- Forks
- 399
- Merge medio
- 1 d 4 h
- PR fusionados (30 d)
- 30
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Sin guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Azure/Azurite
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
Azure/Azurite#2872 · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Azure/Azurite#2865 · 8 reacciones ·
Los mantenedores suelen responder en 1 día
-
Get Blob with Range bytes=-1 returns 500Posiblemente ocupada @hippi345 la tomó hace 14 días. Abierto
Dificultad 3/5 Medio día Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Acquiring a blob lease without a duration causes later requests to return 500Posiblemente ocupada @hippi345 la tomó hace 14 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
PUT to a snapshot URL overwrites the base blobPosiblemente ocupada @hippi345 la tomó hace 14 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
Todos los issues de Azure/Azurite
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Northeastern-Electric-Racing/FinishLine#4660 ·
Los mantenedores suelen responder en 2 días
-
BeOS .json missingAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
mihaip/infinite-mac#475 ·
-
Let TypeScript accept an initial object in ReactiveDictPosiblemente ocupada @yograj-vijay-yadav la tomó hoy. Abiertobug good first issue help wanted workshop
Dificultad 2/5 1-3 horas Aptitud para principiantes 92/100
meteor/meteor#14919 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
marmelab/atomic-crm#401 ·
Los mantenedores suelen responder en 1 día
-
account: profile
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 5 días