Skip to content

Commit bf8cd3e

Browse files
Added support for detecting the end of a request.
1 parent 5aa7dac commit bf8cd3e

File tree

5 files changed

+46
-10
lines changed

5 files changed

+46
-10
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Thin Mode Changes
2525
for string variables.
2626
#) User-defined errors raised by the database no longer display an error help
2727
portal URL.
28+
#) Improved handling of packets with :ref:`asyncio <asyncio>` for recent
29+
database versions.
2830
#) Fixed potential cursor issues when using :ref:`drcp`.
2931
#) Fixed regression when using :ref:`IAM token authentication <iamauth>`
3032
(`issue 288 <https://github.com/oracle/python-oracledb/issues/288>`__).

src/oracledb/impl/thin/capabilities.pyx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ cdef class Capabilities:
4141
uint32_t max_string_size
4242
bint supports_fast_auth
4343
bint supports_oob
44+
bint supports_end_of_request
4445
uint32_t sdu
4546

4647
def __init__(self):
@@ -58,6 +59,9 @@ cdef class Capabilities:
5859
if server_caps[TNS_CCAP_FIELD_VERSION] < self.ttc_field_version:
5960
self.ttc_field_version = server_caps[TNS_CCAP_FIELD_VERSION]
6061
self.compile_caps[TNS_CCAP_FIELD_VERSION] = self.ttc_field_version
62+
if self.ttc_field_version < TNS_CCAP_FIELD_VERSION_19_1 \
63+
or not server_caps[TNS_CCAP_TTC4] & TNS_CCAP_END_OF_REQUEST:
64+
self.compile_caps[TNS_CCAP_TTC4] ^= TNS_CCAP_END_OF_REQUEST
6165

6266
@cython.boundscheck(False)
6367
cdef void _adjust_for_server_runtime_caps(self, bytearray server_caps):
@@ -75,6 +79,15 @@ cdef class Capabilities:
7579
errors._raise_err(errors.ERR_NCHAR_CS_NOT_SUPPORTED,
7680
charset_id=self.ncharset_id)
7781

82+
cdef void _check_supports_end_of_request(self):
83+
"""
84+
Checks whether the end of request flag is sent and sets a boolean to
85+
avoid calculating it each time.
86+
"""
87+
if self.ttc_field_version >= TNS_CCAP_FIELD_VERSION_19_1 \
88+
and self.compile_caps[TNS_CCAP_TTC4] & TNS_CCAP_END_OF_REQUEST:
89+
self.supports_end_of_request = True
90+
7891
@cython.boundscheck(False)
7992
cdef void _init_compile_caps(self):
8093
self.ttc_field_version = TNS_CCAP_FIELD_VERSION_MAX
@@ -109,7 +122,8 @@ cdef class Capabilities:
109122
self.compile_caps[TNS_CCAP_TTC2] = TNS_CCAP_ZLNP
110123
self.compile_caps[TNS_CCAP_OCI2] = TNS_CCAP_DRCP
111124
self.compile_caps[TNS_CCAP_CLIENT_FN] = TNS_CCAP_CLIENT_FN_MAX
112-
self.compile_caps[TNS_CCAP_TTC4] = TNS_CCAP_INBAND_NOTIFICATION
125+
self.compile_caps[TNS_CCAP_TTC4] = TNS_CCAP_INBAND_NOTIFICATION | \
126+
TNS_CCAP_END_OF_REQUEST
113127
self.compile_caps[TNS_CCAP_TTC5] = TNS_CCAP_VECTOR_SUPPORT
114128

115129
@cython.boundscheck(False)

src/oracledb/impl/thin/constants.pxi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ cdef enum:
411411
TNS_MSG_TYPE_ONEWAY_FN = 26
412412
TNS_MSG_TYPE_IMPLICIT_RESULTSET = 27
413413
TNS_MSG_TYPE_RENEGOTIATE = 28
414+
TNS_MSG_TYPE_END_OF_REQUEST = 29
414415
TNS_MSG_TYPE_FAST_AUTH = 34
415416

416417
# parameter keyword numbers
@@ -704,6 +705,7 @@ cdef enum:
704705
TNS_CCAP_DRCP = 0x10
705706
TNS_CCAP_ZLNP = 0x04
706707
TNS_CCAP_INBAND_NOTIFICATION = 0x04
708+
TNS_CCAP_END_OF_REQUEST = 0x20
707709
TNS_CCAP_CLIENT_FN_MAX = 12
708710
TNS_CCAP_VECTOR_SUPPORT = 0x08
709711

src/oracledb/impl/thin/messages.pyx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ cdef class Message:
5151
uint16_t end_to_end_seq_num
5252
bint error_occurred
5353
bint flush_out_binds
54-
bint end_of_request
5554
bint resend
5655
bint retry
5756
object warning
@@ -118,7 +117,7 @@ cdef class Message:
118117
buf.read_ub4(&num_bytes) # oerrdd (logical rowid)
119118
if num_bytes > 0:
120119
buf.skip_raw_bytes_chunked()
121-
self.end_of_request = True
120+
buf._in_request = False
122121

123122
# batch error codes
124123
buf.read_ub2(&num_errors) # batch error codes array
@@ -187,6 +186,8 @@ cdef class Message:
187186
self._process_return_parameters(buf)
188187
elif message_type == TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK:
189188
self._process_server_side_piggyback(buf)
189+
elif message_type == TNS_MSG_TYPE_END_OF_REQUEST:
190+
buf._in_request = False
190191
else:
191192
errors._raise_err(errors.ERR_MESSAGE_TYPE_UNKNOWN,
192193
message_type=message_type,
@@ -301,7 +302,7 @@ cdef class Message:
301302
cdef int process(self, ReadBuffer buf) except -1:
302303
cdef uint8_t message_type
303304
self.flush_out_binds = False
304-
self.end_of_request = False
305+
buf._in_request = True
305306
self._preprocess()
306307
while self._has_more_data(buf):
307308
buf.save_point()
@@ -391,7 +392,7 @@ cdef class MessageWithData(Message):
391392
memcpy(<void*> self.bit_vector, ptr, num_bytes)
392393

393394
cdef bint _has_more_data(self, ReadBuffer buf):
394-
return not self.end_of_request and not self.flush_out_binds
395+
return buf._in_request and not self.flush_out_binds
395396

396397
cdef bint _is_duplicate_data(self, uint32_t column_num):
397398
"""
@@ -1918,6 +1919,7 @@ cdef class DataTypesMessage(Message):
19181919
buf.read_uint16(&conv_data_type)
19191920
if conv_data_type != 0:
19201921
buf.skip_raw_bytes(4)
1922+
buf._caps._check_supports_end_of_request()
19211923

19221924
cdef int _write_message(self, WriteBuffer buf) except -1:
19231925
cdef:
@@ -2215,7 +2217,7 @@ cdef class LobOpMessage(Message):
22152217
object data
22162218

22172219
cdef bint _has_more_data(self, ReadBuffer buf):
2218-
return not self.end_of_request
2220+
return buf._in_request
22192221

22202222
cdef int _initialize_hook(self) except -1:
22212223
"""
@@ -2402,7 +2404,7 @@ cdef class FastAuthMessage(Message):
24022404
bint renegotiate
24032405

24042406
cdef bint _has_more_data(self, ReadBuffer buf):
2405-
return not self.end_of_request
2407+
return buf._in_request
24062408

24072409
cdef int _process_message(self, ReadBuffer buf,
24082410
uint8_t message_type) except -1:
@@ -2419,7 +2421,7 @@ cdef class FastAuthMessage(Message):
24192421
message_type)
24202422
else:
24212423
AuthMessage._process_message(self.auth_message, buf, message_type)
2422-
self.end_of_request = True
2424+
buf._in_request = False
24232425

24242426
cdef int _write_message(self, WriteBuffer buf) except -1:
24252427
"""

src/oracledb/impl/thin/packet.pyx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ cdef class Packet:
5555
uint8_t packet_flags
5656
bytes buf
5757

58+
cdef inline bint has_end_of_request(self):
59+
"""
60+
Returns a boolean indicating if the end of request byte is found at the
61+
end of the packet.
62+
"""
63+
cdef char *ptr = cpython.PyBytes_AS_STRING(self.buf)
64+
return ptr[self.packet_size - 1] == TNS_MSG_TYPE_END_OF_REQUEST
65+
66+
5867
@cython.final
5968
cdef class ChunkedBytesBuffer:
6069

@@ -186,6 +195,7 @@ cdef class ReadBuffer(Buffer):
186195
Transport _transport
187196
list _saved_packets
188197
Capabilities _caps
198+
bint _in_request
189199
object _waiter
190200
object _loop
191201

@@ -314,14 +324,20 @@ cdef class ReadBuffer(Buffer):
314324
"""
315325
Processes a packet. If the packet is a control packet it is processed
316326
immediately and discarded; otherwise, it is added to the list of saved
317-
packets for this response.
327+
packets for this response. If the protocol supports sending the end of
328+
request notification we wait for that message type to be returned at
329+
the end of the packet.
318330
"""
319331
if packet.packet_type == TNS_PACKET_TYPE_CONTROL:
320332
self._process_control_packet(packet)
321333
notify_waiter[0] = False
322334
else:
323335
self._saved_packets.append(packet)
324-
notify_waiter[0] = True
336+
notify_waiter[0] = \
337+
packet.packet_type != TNS_PACKET_TYPE_DATA \
338+
or not self._in_request \
339+
or not self._caps.supports_end_of_request \
340+
or packet.has_end_of_request()
325341

326342
cdef int _read_raw_bytes_and_length(self, const char_type **ptr,
327343
ssize_t *num_bytes) except -1:

0 commit comments

Comments
 (0)