Prevent OOM during streaming deserialization of large responses

When a server-side evaluationTimeout fires mid-stream, the client may
have already queued significant response data. The reader thread could
OOM trying to deserialize large objects (e.g., vertex properties with
huge strings) from the already-queued bytes.

Fixes:
- Reduce MAX_QUEUE_CHUNKS from 512 to 64 (bounds heap usage from
  queued byte[] chunks)
- cancel() now calls markError() instead of markComplete(), causing
  QueueInputStream.read() to throw immediately on next access
- Add error check at top of QueueInputStream.read() so in-progress
  reads from current buffer fail fast when cancelled
- Reader loop checks cancelled flag between readChunk() calls

The combined effect: when the ResultSet is done (timeout, error, or
client abandonment), the reader thread stops consuming data promptly
rather than continuing to deserialize queued bytes until OOM.
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/QueueInputStream.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/QueueInputStream.java
index dac3450..90c15e0 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/QueueInputStream.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/QueueInputStream.java
@@ -36,7 +36,7 @@
      * Maximum number of queued byte[] chunks before enqueue starts discarding.
      * This bounds memory usage if the consumer is not cancelled promptly.
      */
-    private static final int MAX_QUEUE_CHUNKS = 512;
+    private static final int MAX_QUEUE_CHUNKS = 64;
 
     private final BlockingQueue<byte[]> queue = new LinkedBlockingQueue<>();
     private byte[] current;
@@ -78,6 +78,7 @@
 
     @Override
     public int read(final byte[] b, final int off, final int len) throws IOException {
+        if (error != null) throw error;
         if (closed) return -1;
 
         while (current == null || pos >= current.length) {
diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/StreamingResponseConsumer.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/StreamingResponseConsumer.java
index 80ad601..d12a4ed 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/StreamingResponseConsumer.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/StreamingResponseConsumer.java
@@ -213,7 +213,7 @@
         boolean isFirstChunk = true;
         try {
             final InputStreamBuffer buffer = new InputStreamBuffer(queueInputStream);
-            while (true) {
+            while (!cancelled) {
                 final ResponseMessage msg = serializer.readChunk(buffer, isFirstChunk);
                 isFirstChunk = false;