Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions mock_tests/test_readd_no_stale_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import warnings
import weaviate
from weaviate.collections.classes.batch import ErrorObject
from weaviate.proto.v1 import batch_pb2, weaviate_pb2_grpc
from .conftest import MOCK_IP, MOCK_PORT, MOCK_PORT_GRPC, mock_class


class Svc(weaviate_pb2_grpc.WeaviateServicer):
calls = 0

def BatchObjects(self, request, context):
self.calls += 1
if self.calls == 2: # second chunk, once: rate-limit its first object
return batch_pb2.BatchObjectsReply(errors=[{"index": 0, "error": "failed with status: 503 error"}])
return batch_pb2.BatchObjectsReply()


def test_readd_no_stale_errors_and_no_dep020(weaviate_mock, start_grpc_server):
"""Re-adding rate-limited objects must not leave stale errors behind, and
the internal re-add path must not trigger the deprecated
``all_responses`` property's Dep020 warning (issue #2179)."""
weaviate_mock.expect_request(f"/v1/schema/{mock_class['class']}").respond_with_json(mock_class)
weaviate_pb2_grpc.add_WeaviateServicer_to_server(Svc(), start_grpc_server)
client = weaviate.connect_to_local(port=MOCK_PORT, host=MOCK_IP, grpc_port=MOCK_PORT_GRPC)
try:
col = client.collections.use(mock_class["class"])
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
with col.batch.fixed_size(batch_size=2, concurrent_requests=1) as b:
for i in range(4):
b.add_object({"name": f"o{i}"})
r = col.batch.results.objs
dep = [x for x in w if "all_responses" in str(x.message)]
stale = [x for x in r._all_responses if isinstance(x, ErrorObject)]
assert len(dep) == 0, f"deprecated all_responses read during batch: {[str(x.message)[:60] for x in dep]}"
assert len(r.errors) == 0
assert len(stale) == 0, f"stale errors left behind: {[e.message for e in stale]}"
assert len(r._all_responses) == 4
finally:
client.close()
16 changes: 13 additions & 3 deletions weaviate/collections/batch/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,10 +715,20 @@ def __send_batch(
},
errors=new_errors,
has_errors=len(new_errors) > 0,
# Filter by uuid, not by list position: the batch-wide
# index of an errored object is not its position in
# _all_responses, so position-based filtering left the
# re-added objects' stale errors behind from the second
# chunk on. The private field is read directly to avoid
# the deprecated property's Dep020 warning in internal
# code (issue #2179).
_all_responses=[
err
for i, err in enumerate(response_obj.all_responses)
if i not in readded_objects
r
for r in response_obj._all_responses
if not (
isinstance(r, ErrorObject)
and r.object_.uuid in readded_uuids
)
],
elapsed_seconds=response_obj.elapsed_seconds,
)
Expand Down
Loading